source: trunk/third/jpeg/jmemmac.c @ 15227

Revision 15227, 9.3 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15226, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * jmemmac.c
3 *
4 * Copyright (C) 1992-1997, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
7 *
8 * jmemmac.c provides an Apple Macintosh implementation of the system-
9 * dependent portion of the JPEG memory manager.
10 *
11 * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the
12 * JPEG_INTERNALS part of jconfig.h.
13 *
14 * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
15 * instead of malloc and free.  It accurately determines the amount of
16 * memory available by using CompactMem.  Notice that if left to its
17 * own devices, this code can chew up all available space in the
18 * application's zone, with the exception of the rather small "slop"
19 * factor computed in jpeg_mem_available().  The application can ensure
20 * that more space is left over by reducing max_memory_to_use.
21 *
22 * Large images are swapped to disk using temporary files and System 7.0+'s
23 * temporary folder functionality.
24 *
25 * Note that jmemmac.c depends on two features of MacOS that were first
26 * introduced in System 7: FindFolder and the FSSpec-based calls.
27 * If your application uses jmemmac.c and is run under System 6 or earlier,
28 * and the jpeg library decides it needs a temporary file, it will abort,
29 * printing error messages about requiring System 7.  (If no temporary files
30 * are created, it will run fine.)
31 *
32 * If you want to use jmemmac.c in an application that might be used with
33 * System 6 or earlier, then you should remove dependencies on FindFolder
34 * and the FSSpec calls.  You will need to replace FindFolder with some
35 * other mechanism for finding a place to put temporary files, and you
36 * should replace the FSSpec calls with their HFS equivalents:
37 *
38 *     FSpDelete     ->  HDelete
39 *     FSpGetFInfo   ->  HGetFInfo
40 *     FSpCreate     ->  HCreate
41 *     FSpOpenDF     ->  HOpen      *** Note: not HOpenDF ***
42 *     FSMakeFSSpec  ->  (fill in spec by hand.)
43 *
44 * (Use HOpen instead of HOpenDF.  HOpen is just a glue-interface to PBHOpen,
45 * which is on all HFS macs.  HOpenDF is a System 7 addition which avoids the
46 * ages-old problem of names starting with a period.)
47 *
48 * Contributed by Sam Bushell (jsam@iagu.on.net) and
49 * Dan Gildor (gyld@in-touch.com).
50 */
51
52#define JPEG_INTERNALS
53#include "jinclude.h"
54#include "jpeglib.h"
55#include "jmemsys.h"    /* import the system-dependent declarations */
56
57#ifndef USE_MAC_MEMMGR  /* make sure user got configuration right */
58  You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */
59#endif
60
61#include <Memory.h>     /* we use the MacOS memory manager */
62#include <Files.h>      /* we use the MacOS File stuff */
63#include <Folders.h>    /* we use the MacOS HFS stuff */
64#include <Script.h>     /* for smSystemScript */
65#include <Gestalt.h>    /* we use Gestalt to test for specific functionality */
66
67#ifndef TEMP_FILE_NAME          /* can override from jconfig.h or Makefile */
68#define TEMP_FILE_NAME  "JPG%03d.TMP"
69#endif
70
71static int next_file_num;       /* to distinguish among several temp files */
72
73
74/*
75 * Memory allocation and freeing are controlled by the MacOS library
76 * routines NewPtr() and DisposePtr(), which allocate fixed-address
77 * storage.  Unfortunately, the IJG library isn't smart enough to cope
78 * with relocatable storage.
79 */
80
81GLOBAL(void *)
82jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
83{
84  return (void *) NewPtr(sizeofobject);
85}
86
87GLOBAL(void)
88jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
89{
90  DisposePtr((Ptr) object);
91}
92
93
94/*
95 * "Large" objects are treated the same as "small" ones.
96 * NB: we include FAR keywords in the routine declarations simply for
97 * consistency with the rest of the IJG code; FAR should expand to empty
98 * on rational architectures like the Mac.
99 */
100
101GLOBAL(void FAR *)
102jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
103{
104  return (void FAR *) NewPtr(sizeofobject);
105}
106
107GLOBAL(void)
108jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
109{
110  DisposePtr((Ptr) object);
111}
112
113
114/*
115 * This routine computes the total memory space available for allocation.
116 */
117
118GLOBAL(long)
119jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
120                    long max_bytes_needed, long already_allocated)
121{
122  long limit = cinfo->mem->max_memory_to_use - already_allocated;
123  long slop, mem;
124
125  /* Don't ask for more than what application has told us we may use */
126  if (max_bytes_needed > limit && limit > 0)
127    max_bytes_needed = limit;
128  /* Find whether there's a big enough free block in the heap.
129   * CompactMem tries to create a contiguous block of the requested size,
130   * and then returns the size of the largest free block (which could be
131   * much more or much less than we asked for).
132   * We add some slop to ensure we don't use up all available memory.
133   */
134  slop = max_bytes_needed / 16 + 32768L;
135  mem = CompactMem(max_bytes_needed + slop) - slop;
136  if (mem < 0)
137    mem = 0;                    /* sigh, couldn't even get the slop */
138  /* Don't take more than the application says we can have */
139  if (mem > limit && limit > 0)
140    mem = limit;
141  return mem;
142}
143
144
145/*
146 * Backing store (temporary file) management.
147 * Backing store objects are only used when the value returned by
148 * jpeg_mem_available is less than the total space needed.  You can dispense
149 * with these routines if you have plenty of virtual memory; see jmemnobs.c.
150 */
151
152
153METHODDEF(void)
154read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
155                    void FAR * buffer_address,
156                    long file_offset, long byte_count)
157{
158  long bytes = byte_count;
159  long retVal;
160
161  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
162    ERREXIT(cinfo, JERR_TFILE_SEEK);
163
164  retVal = FSRead ( info->temp_file, &bytes,
165                    (unsigned char *) buffer_address );
166  if ( retVal != noErr || bytes != byte_count )
167    ERREXIT(cinfo, JERR_TFILE_READ);
168}
169
170
171METHODDEF(void)
172write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
173                     void FAR * buffer_address,
174                     long file_offset, long byte_count)
175{
176  long bytes = byte_count;
177  long retVal;
178
179  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
180    ERREXIT(cinfo, JERR_TFILE_SEEK);
181
182  retVal = FSWrite ( info->temp_file, &bytes,
183                     (unsigned char *) buffer_address );
184  if ( retVal != noErr || bytes != byte_count )
185    ERREXIT(cinfo, JERR_TFILE_WRITE);
186}
187
188
189METHODDEF(void)
190close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
191{
192  FSClose ( info->temp_file );
193  FSpDelete ( &(info->tempSpec) );
194}
195
196
197/*
198 * Initial opening of a backing-store object.
199 *
200 * This version uses FindFolder to find the Temporary Items folder,
201 * and puts the temporary file in there.
202 */
203
204GLOBAL(void)
205jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
206                         long total_bytes_needed)
207{
208  short         tmpRef, vRefNum;
209  long          dirID;
210  FInfo         finderInfo;
211  FSSpec        theSpec;
212  Str255        fName;
213  OSErr         osErr;
214  long          gestaltResponse = 0;
215
216  /* Check that FSSpec calls are available. */
217  osErr = Gestalt( gestaltFSAttr, &gestaltResponse );
218  if ( ( osErr != noErr )
219       || !( gestaltResponse & (1<<gestaltHasFSSpecCalls) ) )
220    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required");
221  /* TO DO: add a proper error message to jerror.h. */
222
223  /* Check that FindFolder is available. */
224  osErr = Gestalt( gestaltFindFolderAttr, &gestaltResponse );
225  if ( ( osErr != noErr )
226       || !( gestaltResponse & (1<<gestaltFindFolderPresent) ) )
227    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required.");
228  /* TO DO: add a proper error message to jerror.h. */
229
230  osErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
231                       &vRefNum, &dirID );
232  if ( osErr != noErr )
233    ERREXITS(cinfo, JERR_TFILE_CREATE, "- temporary items folder unavailable");
234  /* TO DO: Try putting the temp files somewhere else. */
235
236  /* Keep generating file names till we find one that's not in use */
237  for (;;) {
238    next_file_num++;            /* advance counter */
239
240    sprintf(info->temp_name, TEMP_FILE_NAME, next_file_num);
241    strcpy ( (Ptr)fName+1, info->temp_name );
242    *fName = strlen (info->temp_name);
243    osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec );
244
245    if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr )
246      break;
247  }
248
249  osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript );
250  if ( osErr != noErr )
251    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
252
253  osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) );
254  if ( osErr != noErr )
255    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
256
257  info->tempSpec = theSpec;
258
259  info->read_backing_store = read_backing_store;
260  info->write_backing_store = write_backing_store;
261  info->close_backing_store = close_backing_store;
262  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
263}
264
265
266/*
267 * These routines take care of any system-dependent initialization and
268 * cleanup required.
269 */
270
271GLOBAL(long)
272jpeg_mem_init (j_common_ptr cinfo)
273{
274  next_file_num = 0;
275
276  /* max_memory_to_use will be initialized to FreeMem()'s result;
277   * the calling application might later reduce it, for example
278   * to leave room to invoke multiple JPEG objects.
279   * Note that FreeMem returns the total number of free bytes;
280   * it may not be possible to allocate a single block of this size.
281   */
282  return FreeMem();
283}
284
285GLOBAL(void)
286jpeg_mem_term (j_common_ptr cinfo)
287{
288  /* no work */
289}
Note: See TracBrowser for help on using the repository browser.