aboutsummaryrefslogtreecommitdiff
path: root/SrcShared/jpeg/jmemmac.c
blob: fb2dcf53249d284a22df7019e12b3e59c9952c5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#if 1
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h"		/* import the system-dependent declarations */

#include "Platform.h"		/* Platform_AllocateMemory */

/*
 * Memory allocation and freeing are controlled by the regular library
 * routines malloc() and free().
 */

GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
  return (void *) malloc(sizeofobject);
}

GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
  free(object);
}


/*
 * "Large" objects are treated the same as "small" ones.
 * NB: although we include FAR keywords in the routine declarations,
 * this file won't actually work in 80x86 small/medium model; at least,
 * you probably won't be able to process useful-size images in only 64KB.
 */

GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
  return (void FAR *) Platform_AllocateMemory(sizeofobject);
}

GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
  Platform_DisposeMemory(object);
}


/*
 * This routine computes the total memory space available for allocation.
 * Here we always say, "we got all you want bud!"
 */

GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
		    long max_bytes_needed, long already_allocated)
{
  return max_bytes_needed;
}


/*
 * Backing store (temporary file) management.
 * Since jpeg_mem_available always promised the moon,
 * this should never be called and we can just error out.
 */

GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
			 long total_bytes_needed)
{
  ERREXIT(cinfo, JERR_NO_BACKING_STORE);
}


/*
 * These routines take care of any system-dependent initialization and
 * cleanup required.  Here, there isn't any.
 */

GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
  return 0;			/* just set max_memory_to_use to 0 */
}

GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
  /* no work */
}

#else

/*
 * jmemmac.c
 *
 * Copyright (C) 1992-1997, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * jmemmac.c provides an Apple Macintosh implementation of the system-
 * dependent portion of the JPEG memory manager.
 *
 * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the
 * JPEG_INTERNALS part of jconfig.h.
 *
 * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
 * instead of malloc and free.  It accurately determines the amount of
 * memory available by using CompactMem.  Notice that if left to its
 * own devices, this code can chew up all available space in the
 * application's zone, with the exception of the rather small "slop"
 * factor computed in jpeg_mem_available().  The application can ensure
 * that more space is left over by reducing max_memory_to_use.
 *
 * Large images are swapped to disk using temporary files and System 7.0+'s
 * temporary folder functionality.
 *
 * Note that jmemmac.c depends on two features of MacOS that were first
 * introduced in System 7: FindFolder and the FSSpec-based calls.
 * If your application uses jmemmac.c and is run under System 6 or earlier,
 * and the jpeg library decides it needs a temporary file, it will abort,
 * printing error messages about requiring System 7.  (If no temporary files
 * are created, it will run fine.)
 *
 * If you want to use jmemmac.c in an application that might be used with
 * System 6 or earlier, then you should remove dependencies on FindFolder
 * and the FSSpec calls.  You will need to replace FindFolder with some
 * other mechanism for finding a place to put temporary files, and you
 * should replace the FSSpec calls with their HFS equivalents:
 *
 *     FSpDelete     ->  HDelete
 *     FSpGetFInfo   ->  HGetFInfo
 *     FSpCreate     ->  HCreate
 *     FSpOpenDF     ->  HOpen      *** Note: not HOpenDF ***
 *     FSMakeFSSpec  ->  (fill in spec by hand.)
 *
 * (Use HOpen instead of HOpenDF.  HOpen is just a glue-interface to PBHOpen,
 * which is on all HFS macs.  HOpenDF is a System 7 addition which avoids the
 * ages-old problem of names starting with a period.)
 *
 * Contributed by Sam Bushell (jsam@iagu.on.net) and
 * Dan Gildor (gyld@in-touch.com).
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h"    /* import the system-dependent declarations */

#ifndef USE_MAC_MEMMGR	/* make sure user got configuration right */
  You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */
#endif

#include <Memory.h>     /* we use the MacOS memory manager */
#include <Files.h>      /* we use the MacOS File stuff */
#include <Folders.h>    /* we use the MacOS HFS stuff */
#include <Script.h>     /* for smSystemScript */
#include <Gestalt.h>    /* we use Gestalt to test for specific functionality */

#ifndef TEMP_FILE_NAME		/* can override from jconfig.h or Makefile */
#define TEMP_FILE_NAME  "JPG%03d.TMP"
#endif

static int next_file_num;	/* to distinguish among several temp files */


/*
 * Memory allocation and freeing are controlled by the MacOS library
 * routines NewPtr() and DisposePtr(), which allocate fixed-address
 * storage.  Unfortunately, the IJG library isn't smart enough to cope
 * with relocatable storage.
 */

GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
  return (void *) NewPtr(sizeofobject);
}

GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
  DisposePtr((Ptr) object);
}


/*
 * "Large" objects are treated the same as "small" ones.
 * NB: we include FAR keywords in the routine declarations simply for
 * consistency with the rest of the IJG code; FAR should expand to empty
 * on rational architectures like the Mac.
 */

GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
  return (void FAR *) NewPtr(sizeofobject);
}

GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
  DisposePtr((Ptr) object);
}


/*
 * This routine computes the total memory space available for allocation.
 */

GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
		    long max_bytes_needed, long already_allocated)
{
  long limit = cinfo->mem->max_memory_to_use - already_allocated;
  long slop, mem;

  /* Don't ask for more than what application has told us we may use */
  if (max_bytes_needed > limit && limit > 0)
    max_bytes_needed = limit;
  /* Find whether there's a big enough free block in the heap.
   * CompactMem tries to create a contiguous block of the requested size,
   * and then returns the size of the largest free block (which could be
   * much more or much less than we asked for).
   * We add some slop to ensure we don't use up all available memory.
   */
  slop = max_bytes_needed / 16 + 32768L;
  mem = CompactMem(max_bytes_needed + slop) - slop;
  if (mem < 0)
    mem = 0;			/* sigh, couldn't even get the slop */
  /* Don't take more than the application says we can have */
  if (mem > limit && limit > 0)
    mem = limit;
  return mem;
}


/*
 * Backing store (temporary file) management.
 * Backing store objects are only used when the value returned by
 * jpeg_mem_available is less than the total space needed.  You can dispense
 * with these routines if you have plenty of virtual memory; see jmemnobs.c.
 */


METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
		    void FAR * buffer_address,
		    long file_offset, long byte_count)
{
  long bytes = byte_count;
  long retVal;

  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
    ERREXIT(cinfo, JERR_TFILE_SEEK);

  retVal = FSRead ( info->temp_file, &bytes,
		    (unsigned char *) buffer_address );
  if ( retVal != noErr || bytes != byte_count )
    ERREXIT(cinfo, JERR_TFILE_READ);
}


METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
		     void FAR * buffer_address,
		     long file_offset, long byte_count)
{
  long bytes = byte_count;
  long retVal;

  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
    ERREXIT(cinfo, JERR_TFILE_SEEK);

  retVal = FSWrite ( info->temp_file, &bytes,
		     (unsigned char *) buffer_address );
  if ( retVal != noErr || bytes != byte_count )
    ERREXIT(cinfo, JERR_TFILE_WRITE);
}


METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
  FSClose ( info->temp_file );
  FSpDelete ( &(info->tempSpec) );
}


/*
 * Initial opening of a backing-store object.
 *
 * This version uses FindFolder to find the Temporary Items folder,
 * and puts the temporary file in there.
 */

GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
			 long total_bytes_needed)
{
  short         tmpRef, vRefNum;
  long          dirID;
  FInfo         finderInfo;
  FSSpec        theSpec;
  Str255        fName;
  OSErr         osErr;
  long          gestaltResponse = 0;

  /* Check that FSSpec calls are available. */
  osErr = Gestalt( gestaltFSAttr, &gestaltResponse );
  if ( ( osErr != noErr )
       || !( gestaltResponse & (1<<gestaltHasFSSpecCalls) ) )
    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required");
  /* TO DO: add a proper error message to jerror.h. */

  /* Check that FindFolder is available. */
  osErr = Gestalt( gestaltFindFolderAttr, &gestaltResponse );
  if ( ( osErr != noErr )
       || !( gestaltResponse & (1<<gestaltFindFolderPresent) ) )
    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required.");
  /* TO DO: add a proper error message to jerror.h. */

  osErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
                       &vRefNum, &dirID );
  if ( osErr != noErr )
    ERREXITS(cinfo, JERR_TFILE_CREATE, "- temporary items folder unavailable");
  /* TO DO: Try putting the temp files somewhere else. */

  /* Keep generating file names till we find one that's not in use */
  for (;;) {
    next_file_num++;		/* advance counter */

    sprintf(info->temp_name, TEMP_FILE_NAME, next_file_num);
    strcpy ( (Ptr)fName+1, info->temp_name );
    *fName = strlen (info->temp_name);
    osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec );

    if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr )
      break;
  }

  osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript );
  if ( osErr != noErr )
    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);

  osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) );
  if ( osErr != noErr )
    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);

  info->tempSpec = theSpec;

  info->read_backing_store = read_backing_store;
  info->write_backing_store = write_backing_store;
  info->close_backing_store = close_backing_store;
  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
}


/*
 * These routines take care of any system-dependent initialization and
 * cleanup required.
 */

GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
  next_file_num = 0;

  /* max_memory_to_use will be initialized to FreeMem()'s result;
   * the calling application might later reduce it, for example
   * to leave room to invoke multiple JPEG objects.
   * Note that FreeMem returns the total number of free bytes;
   * it may not be possible to allocate a single block of this size.
   */
  return FreeMem();
}

GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
  /* no work */
}

#endif