170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jmemdos.c
370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1992-1997, Thomas G. Lane.
570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software.
670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file.
770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file provides an MS-DOS-compatible implementation of the system-
970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * dependent portion of the JPEG memory manager.  Temporary data can be
1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * stored in extended or expanded memory as well as in regular DOS files.
1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If you use this file, you must be sure that NEED_FAR_POINTERS is defined
1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * if you compile in a small-data memory model; it should NOT be defined if
1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * you use a large-data memory model.  This file is not recommended if you
1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Also, this code will NOT work if struct fields are aligned on greater than
1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 2-byte boundaries.
1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Based on code contributed by Ge' Weijers.
2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If you have both extended and expanded memory, you may want to change the
2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * order in which they are tried in jopen_backing_store.  On a 286 machine
2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * expanded memory is usually faster, since extended memory access involves
2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * an expensive protected-mode-and-back switch.  On 386 and better, extended
2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * memory is usually faster.  As distributed, the code tries extended memory
2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * first (what? not everyone has a 386? :-).
2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * You can disable use of extended/expanded memory entirely by altering these
3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifndef XMS_SUPPORTED
3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define XMS_SUPPORTED  1
3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifndef EMS_SUPPORTED
3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define EMS_SUPPORTED  1
3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define JPEG_INTERNALS
4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jinclude.h"
4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jpeglib.h"
4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jmemsys.h"		/* import the system-dependent declarations */
4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare these */
4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern void * malloc JPP((size_t size));
4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern void free JPP((void *ptr));
5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern char * getenv JPP((const char * name));
5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef NEED_FAR_POINTERS
5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef __TURBOC__
5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* These definitions work for Borland C (Turbo C) */
5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <alloc.h>		/* need farmalloc(), farfree() */
5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_malloc(x)	farmalloc(x)
5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_free(x)	farfree(x)
6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else
6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* These definitions work for Microsoft C and compatible compilers */
6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <malloc.h>		/* need _fmalloc(), _ffree() */
6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_malloc(x)	_fmalloc(x)
6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_free(x)	_ffree(x)
6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else /* not NEED_FAR_POINTERS */
6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_malloc(x)	malloc(x)
7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define far_free(x)	free(x)
7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* NEED_FAR_POINTERS */
7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define READ_BINARY	"r"
7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else
7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define READ_BINARY	"rb"
7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifndef USE_MSDOS_MEMMGR	/* make sure user got configuration right */
8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if MAX_ALLOC_CHUNK >= 65535L	/* make sure jconfig.h got this right */
8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Declarations for assembly-language support routines (see jmemdosa.asm).
9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The functions are declared "far" as are all their pointer arguments;
9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * this ensures the assembly source code will work regardless of the
9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * compiler memory model.  We assume "short" is 16 bits, "long" is 32.
9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef void far * XMSDRIVER;	/* actually a pointer to code */
9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct {		/* registers for calling XMS driver */
9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	unsigned short ax, dx, bx;
10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	void far * ds_si;
10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } XMScontext;
10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct {		/* registers for calling EMS driver */
10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	unsigned short ax, dx, bx;
10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	void far * ds_si;
10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } EMScontext;
10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jdos_open JPP((short far * handle, char far * filename));
10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jdos_close JPP((short handle));
10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jdos_seek JPP((short handle, long offset));
11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jdos_read JPP((short handle, void far * buffer,
11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine				unsigned short count));
11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jdos_write JPP((short handle, void far * buffer,
11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine				 unsigned short count));
11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern void far jxms_getdriver JPP((XMSDRIVER far *));
11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern short far jems_available JPP((void));
11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineextern void far jems_calldriver JPP((EMScontext far *));
11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Selection of a file name for a temporary file.
12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is highly system-dependent, and you may want to customize it.
12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic int next_file_num;	/* to distinguish among several temp files */
12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void)
12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineselect_file_name (char * fname)
12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  const char * env;
13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  char * ptr;
13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  FILE * tfile;
13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Keep generating file names till we find one that's not in use */
13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (;;) {
13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Get temp directory name from environment TMP or TEMP variable;
13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * if none, use "."
13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if ((env = (const char *) getenv("TMP")) == NULL)
14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if ((env = (const char *) getenv("TEMP")) == NULL)
14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	env = ".";
14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (*env == '\0')		/* null string means "." */
14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      env = ".";
14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ptr = fname;		/* copy name to fname */
14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    while (*env != '\0')
14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *ptr++ = *env++;
14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (ptr[-1] != '\\' && ptr[-1] != '/')
14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *ptr++ = '\\';		/* append backslash if not in env variable */
14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Append a suitable file name */
15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    next_file_num++;		/* advance counter */
15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    sprintf(ptr, "JPG%03d.TMP", next_file_num);
15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Probe to see if file name is already in use */
15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if ((tfile = fopen(fname, READ_BINARY)) == NULL)
15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    fclose(tfile);		/* oops, it's there; close tfile & try again */
15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Near-memory allocation and freeing are controlled by the regular library
16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * routines malloc() and free().
16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void *)
16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return (void *) malloc(sizeofobject);
16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  free(object);
17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * "Large" objects are allocated in far memory, if possible
18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void FAR *)
18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return (void FAR *) far_malloc(sizeofobject);
18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  far_free(object);
19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This routine computes the total memory space available for allocation.
19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * It's impossible to do this in a portable way; our current solution is
19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to make the user tell us (with a default value set at compile time).
19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If you can actually get the available space, it's a good idea to subtract
20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * a slop factor of 5% or so.
20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifndef DEFAULT_MAX_MEM		/* so can override from makefile */
20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DEFAULT_MAX_MEM		300000L /* for total usage about 450K */
20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(long)
20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		    long max_bytes_needed, long already_allocated)
21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return cinfo->mem->max_memory_to_use - already_allocated;
21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Backing store (temporary file) management.
21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Backing store objects are only used when the value returned by
21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jpeg_mem_available is less than the total space needed.  You can dispense
21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * with these routines if you have plenty of virtual memory; see jmemnobs.c.
22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For MS-DOS we support three types of backing storage:
22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   1. Conventional DOS files.  We access these by direct DOS calls rather
22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      than via the stdio package.  This provides a bit better performance,
22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      but the real reason is that the buffers to be read or written are FAR.
22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      The stdio library for small-data memory models can't cope with that.
22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   2. Extended memory, accessed per the XMS V2.0 specification.
22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * You'll need copies of those specs to make sense of the related code.
23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The specs are available by Internet FTP from the SIMTEL archives
23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (oak.oakland.edu and its various mirror sites).  See files
23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Access methods for a DOS file.
23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_file_store (j_common_ptr cinfo, backing_store_ptr info,
24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 void FAR * buffer_address,
24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 long file_offset, long byte_count)
24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (jdos_seek(info->handle.file_handle, file_offset))
24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_TFILE_SEEK);
24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (byte_count > 65535L)	/* safety check */
25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (jdos_read(info->handle.file_handle, buffer_address,
25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		(unsigned short) byte_count))
25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_TFILE_READ);
25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinewrite_file_store (j_common_ptr cinfo, backing_store_ptr info,
26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  void FAR * buffer_address,
26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  long file_offset, long byte_count)
26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (jdos_seek(info->handle.file_handle, file_offset))
26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_TFILE_SEEK);
26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (byte_count > 65535L)	/* safety check */
26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (jdos_write(info->handle.file_handle, buffer_address,
26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 (unsigned short) byte_count))
27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_TFILE_WRITE);
27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineclose_file_store (j_common_ptr cinfo, backing_store_ptr info)
27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jdos_close(info->handle.file_handle);	/* close the file */
27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  remove(info->temp_name);	/* delete the file */
27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* If your system doesn't have remove(), try unlink() instead.
28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * remove() is the ANSI-standard name for this function, but
28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * unlink() was more common in pre-ANSI systems.
28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineopen_file_store (j_common_ptr cinfo, backing_store_ptr info,
28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 long total_bytes_needed)
29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  short handle;
29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  select_file_name(info->temp_name);
29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* might as well exit since jpeg_open_backing_store will fail anyway */
29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->handle.file_handle = handle;
30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->read_backing_store = read_file_store;
30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->write_backing_store = write_file_store;
30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->close_backing_store = close_file_store;
30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;			/* succeeded */
30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Access methods for extended memory.
31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if XMS_SUPPORTED
31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic XMSDRIVER xms_driver;	/* saved address of XMS driver */
31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef union {			/* either long offset or real-mode pointer */
31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	long offset;
31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	void far * ptr;
31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } XMSPTR;
32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct {		/* XMS move specification structure */
32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	long length;
32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	XMSH src_handle;
32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	XMSPTR src;
32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	XMSH dst_handle;
32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	XMSPTR dst;
32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } XMSspec;
32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define ODD(X)	(((X) & 1L) != 0)
33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_xms_store (j_common_ptr cinfo, backing_store_ptr info,
33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		void FAR * buffer_address,
33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		long file_offset, long byte_count)
33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMScontext ctx;
33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMSspec spec;
33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  char endbuffer[2];
34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* The XMS driver can't cope with an odd length, so handle the last byte
34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * specially if byte_count is odd.  We don't expect this to be common.
34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.length = byte_count & (~ 1L);
34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.src_handle = info->handle.xms_handle;
34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.src.offset = file_offset;
34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.dst_handle = 0;
34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.dst.ptr = buffer_address;
35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ds_si = (void far *) & spec;
35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x0b00;		/* EMB move */
35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ctx.ax != 1)
35570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_XMS_READ);
35670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
35770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ODD(byte_count)) {
35870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    read_xms_store(cinfo, info, (void FAR *) endbuffer,
35970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		   file_offset + byte_count - 1L, 2L);
36070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
36170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
36270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
36370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
36470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
36570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
36670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinewrite_xms_store (j_common_ptr cinfo, backing_store_ptr info,
36770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 void FAR * buffer_address,
36870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 long file_offset, long byte_count)
36970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
37070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMScontext ctx;
37170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMSspec spec;
37270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  char endbuffer[2];
37370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
37470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* The XMS driver can't cope with an odd length, so handle the last byte
37570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * specially if byte_count is odd.  We don't expect this to be common.
37670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
37770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
37870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.length = byte_count & (~ 1L);
37970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.src_handle = 0;
38070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.src.ptr = buffer_address;
38170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.dst_handle = info->handle.xms_handle;
38270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.dst.offset = file_offset;
38370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
38470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ds_si = (void far *) & spec;
38570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x0b00;		/* EMB move */
38670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
38770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ctx.ax != 1)
38870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_XMS_WRITE);
38970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
39070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ODD(byte_count)) {
39170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    read_xms_store(cinfo, info, (void FAR *) endbuffer,
39270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		   file_offset + byte_count - 1L, 2L);
39370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
39470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    write_xms_store(cinfo, info, (void FAR *) endbuffer,
39570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		    file_offset + byte_count - 1L, 2L);
39670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
39770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
39870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
39970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
40070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
40170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineclose_xms_store (j_common_ptr cinfo, backing_store_ptr info)
40270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
40370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMScontext ctx;
40470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
40570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.dx = info->handle.xms_handle;
40670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x0a00;
40770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
40870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
40970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* we ignore any error return from the driver */
41070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
41170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
41470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineopen_xms_store (j_common_ptr cinfo, backing_store_ptr info,
41570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		long total_bytes_needed)
41670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
41770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  XMScontext ctx;
41870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Get address of XMS driver */
42070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_getdriver((XMSDRIVER far *) & xms_driver);
42170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (xms_driver == NULL)
42270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;		/* no driver to be had */
42370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
42470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Get version number, must be >= 2.00 */
42570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x0000;
42670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
42770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ctx.ax < (unsigned short) 0x0200)
42870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
42970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
43070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Try to get space (expressed in kilobytes) */
43170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
43270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x0900;
43370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
43470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (ctx.ax != 1)
43570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
43670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
43770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Succeeded, save the handle and away we go */
43870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->handle.xms_handle = ctx.dx;
43970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->read_backing_store = read_xms_store;
44070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->write_backing_store = write_xms_store;
44170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->close_backing_store = close_xms_store;
44270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
44370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;			/* succeeded */
44470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
44570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
44670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* XMS_SUPPORTED */
44770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
44870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
44970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
45070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Access methods for expanded memory.
45170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
45270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
45370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if EMS_SUPPORTED
45470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
45570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* The EMS move specification structure requires word and long fields aligned
45670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * at odd byte boundaries.  Some compilers will align struct fields at even
45770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * byte boundaries.  While it's usually possible to force byte alignment,
45870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * that causes an overall performance penalty and may pose problems in merging
45970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * JPEG into a larger application.  Instead we accept some rather dirty code
46070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * here.  Note this code would fail if the hardware did not allow odd-byte
46170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * word & long accesses, but all 80x86 CPUs do.
46270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
46370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
46470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef void far * EMSPTR;
46570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
46670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef union {			/* EMS move specification structure */
46770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	long length;		/* It's easy to access first 4 bytes */
46870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	char bytes[18];		/* Misaligned fields in here! */
46970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } EMSspec;
47070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
47170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Macros for accessing misaligned fields */
47270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define FIELD_AT(spec,offset,type)  (*((type *) &(spec.bytes[offset])))
47370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define SRC_TYPE(spec)		FIELD_AT(spec,4,char)
47470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define SRC_HANDLE(spec)	FIELD_AT(spec,5,EMSH)
47570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define SRC_OFFSET(spec)	FIELD_AT(spec,7,unsigned short)
47670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define SRC_PAGE(spec)		FIELD_AT(spec,9,unsigned short)
47770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define SRC_PTR(spec)		FIELD_AT(spec,7,EMSPTR)
47870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DST_TYPE(spec)		FIELD_AT(spec,11,char)
47970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DST_HANDLE(spec)	FIELD_AT(spec,12,EMSH)
48070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DST_OFFSET(spec)	FIELD_AT(spec,14,unsigned short)
48170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DST_PAGE(spec)		FIELD_AT(spec,16,unsigned short)
48270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define DST_PTR(spec)		FIELD_AT(spec,14,EMSPTR)
48370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define EMSPAGESIZE	16384L	/* gospel, see the EMS specs */
48570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define HIBYTE(W)  (((W) >> 8) & 0xFF)
48770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define LOBYTE(W)  ((W) & 0xFF)
48870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
49070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
49170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_ems_store (j_common_ptr cinfo, backing_store_ptr info,
49270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		void FAR * buffer_address,
49370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		long file_offset, long byte_count)
49470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
49570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMScontext ctx;
49670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMSspec spec;
49770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
49870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.length = byte_count;
49970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_TYPE(spec) = 1;
50070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_HANDLE(spec) = info->handle.ems_handle;
50170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
50270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
50370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_TYPE(spec) = 0;
50470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_HANDLE(spec) = 0;
50570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_PTR(spec)    = buffer_address;
50670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
50770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ds_si = (void far *) & spec;
50870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x5700;		/* move memory region */
50970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
51070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (HIBYTE(ctx.ax) != 0)
51170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_EMS_READ);
51270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
51370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
51470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
51570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
51670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinewrite_ems_store (j_common_ptr cinfo, backing_store_ptr info,
51770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 void FAR * buffer_address,
51870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 long file_offset, long byte_count)
51970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
52070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMScontext ctx;
52170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMSspec spec;
52270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
52370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  spec.length = byte_count;
52470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_TYPE(spec) = 0;
52570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_HANDLE(spec) = 0;
52670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  SRC_PTR(spec)    = buffer_address;
52770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_TYPE(spec) = 1;
52870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_HANDLE(spec) = info->handle.ems_handle;
52970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
53070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
53170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
53270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ds_si = (void far *) & spec;
53370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x5700;		/* move memory region */
53470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
53570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (HIBYTE(ctx.ax) != 0)
53670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_EMS_WRITE);
53770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
53870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
53970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
54070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
54170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineclose_ems_store (j_common_ptr cinfo, backing_store_ptr info)
54270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
54370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMScontext ctx;
54470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
54570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x4500;
54670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.dx = info->handle.ems_handle;
54770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
54870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
54970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* we ignore any error return from the driver */
55070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
55170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
55270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
55370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
55470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineopen_ems_store (j_common_ptr cinfo, backing_store_ptr info,
55570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		long total_bytes_needed)
55670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
55770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  EMScontext ctx;
55870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
55970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Is EMS driver there? */
56070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (! jems_available())
56170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
56270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Get status, make sure EMS is OK */
56470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x4000;
56570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
56670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (HIBYTE(ctx.ax) != 0)
56770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
56870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Get version, must be >= 4.0 */
57070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x4600;
57170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
57270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
57370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
57470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
57570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Try to allocate requested space */
57670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.ax = 0x4300;
57770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
57870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jems_calldriver((EMScontext far *) & ctx);
57970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (HIBYTE(ctx.ax) != 0)
58070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return FALSE;
58170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
58270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Succeeded, save the handle and away we go */
58370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->handle.ems_handle = ctx.dx;
58470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->read_backing_store = read_ems_store;
58570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->write_backing_store = write_ems_store;
58670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  info->close_backing_store = close_ems_store;
58770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
58870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;			/* succeeded */
58970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
59070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
59170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* EMS_SUPPORTED */
59270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
59370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
59470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
59570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Initial opening of a backing-store object.
59670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
59770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
59870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
59970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
60070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine			 long total_bytes_needed)
60170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
60270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Try extended memory, then expanded memory, then regular file. */
60370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if XMS_SUPPORTED
60470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (open_xms_store(cinfo, info, total_bytes_needed))
60570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return;
60670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
60770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if EMS_SUPPORTED
60870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (open_ems_store(cinfo, info, total_bytes_needed))
60970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return;
61070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
61170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (open_file_store(cinfo, info, total_bytes_needed))
61270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    return;
61370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  ERREXITS(cinfo, JERR_TFILE_CREATE, "");
61470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
61570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
61670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
61770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
61870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These routines take care of any system-dependent initialization and
61970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * cleanup required.
62070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
62170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
62270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(long)
62370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_mem_init (j_common_ptr cinfo)
62470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
62570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  next_file_num = 0;		/* initialize temp file name generator */
62670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return DEFAULT_MAX_MEM;	/* default for max_memory_to_use */
62770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
62870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
62970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
63070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_mem_term (j_common_ptr cinfo)
63170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
63270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Microsoft C, at least in v6.00A, will not successfully reclaim freed
63370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
63470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
63570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef NEED_FHEAPMIN
63670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  _fheapmin();
63770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif
63870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
639