2
/* pngmem.c - stub functions for memory allocation
4
* libpng 1.0.8 - July 24, 2000
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
7
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10
* This file provides a location for all memory allocation. Users who
11
* need special memory handling are expected to supply replacement
12
* functions for png_malloc() and png_free(), and to use
13
* png_create_read_struct_2() and png_create_write_struct_2() to
14
* identify the replacement functions.
20
/* Borland DOS special memory handler */
21
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
22
/* if you change this, be sure to change the one in png.h also */
24
/* Allocate memory for a png_struct. The malloc and memset can be replaced
25
by a single call to calloc() if this is thought to improve performance. */
26
png_voidp /* PRIVATE */
27
png_create_struct(int type)
29
#ifdef PNG_USER_MEM_SUPPORTED
30
return (png_create_struct_2(type, NULL));
33
/* Alternate version of png_create_struct, for use with user-defined malloc. */
34
png_voidp /* PRIVATE */
35
png_create_struct_2(int type, png_malloc_ptr malloc_fn)
37
#endif /* PNG_USER_MEM_SUPPORTED */
41
if (type == PNG_STRUCT_INFO)
42
size = sizeof(png_info);
43
else if (type == PNG_STRUCT_PNG)
44
size = sizeof(png_struct);
46
return ((png_voidp)NULL);
48
#ifdef PNG_USER_MEM_SUPPORTED
51
if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
52
png_memset(struct_ptr, 0, size);
55
#endif /* PNG_USER_MEM_SUPPORTED */
56
if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
58
png_memset(struct_ptr, 0, size);
64
/* Free memory allocated by a png_create_struct() call */
66
png_destroy_struct(png_voidp struct_ptr)
68
#ifdef PNG_USER_MEM_SUPPORTED
69
png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
72
/* Free memory allocated by a png_create_struct() call */
74
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
77
if (struct_ptr != NULL)
79
#ifdef PNG_USER_MEM_SUPPORTED
82
png_struct dummy_struct;
83
png_structp png_ptr = &dummy_struct;
84
(*(free_fn))(png_ptr, struct_ptr);
87
#endif /* PNG_USER_MEM_SUPPORTED */
92
/* Allocate memory. For reasonable files, size should never exceed
93
* 64K. However, zlib may allocate more then 64K if you don't tell
94
* it not to. See zconf.h and png.h for more information. zlib does
95
* need to allocate exactly 64K, so whatever you call here must
96
* have the ability to do that.
98
* Borland seems to have a problem in DOS mode for exactly 64K.
99
* It gives you a segment with an offset of 8 (perhaps to store its
100
* memory stuff). zlib doesn't like this at all, so we have to
101
* detect and deal with it. This code should not be needed in
102
* Windows or OS/2 modes, and only in 16 bit mode. This code has
103
* been updated by Alexander Lehmann for version 0.89 to waste less
106
* Note that we can't use png_size_t for the "size" declaration,
107
* since on some systems a png_size_t is a 16-bit quantity, and as a
108
* result, we would be truncating potentially larger memory requests
109
* (which should cause a fatal error) and introducing major problems.
112
png_malloc(png_structp png_ptr, png_uint_32 size)
114
#ifndef PNG_USER_MEM_SUPPORTED
117
if (png_ptr == NULL || size == 0)
118
return ((png_voidp)NULL);
120
#ifdef PNG_USER_MEM_SUPPORTED
121
if(png_ptr->malloc_fn != NULL)
122
return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
124
return png_malloc_default(png_ptr, size);
128
png_malloc_default(png_structp png_ptr, png_uint_32 size)
131
#endif /* PNG_USER_MEM_SUPPORTED */
133
#ifdef PNG_MAX_MALLOC_64K
134
if (size > (png_uint_32)65536L)
135
png_error(png_ptr, "Cannot Allocate > 64K");
138
if (size == (png_uint_32)65536L)
140
if (png_ptr->offset_table == NULL)
142
/* try to see if we need to do any of this fancy stuff */
143
ret = farmalloc(size);
144
if (ret == NULL || ((png_size_t)ret & 0xffff))
147
png_uint_32 total_size;
150
png_byte huge * hptr;
158
if(png_ptr->zlib_window_bits > 14)
159
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
162
if (png_ptr->zlib_mem_level >= 7)
163
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
167
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
169
table = farmalloc(total_size);
173
png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
176
if ((png_size_t)table & 0xfff0)
178
png_error(png_ptr, "Farmalloc didn't return normalized pointer");
181
png_ptr->offset_table = table;
182
png_ptr->offset_table_ptr = farmalloc(num_blocks *
185
if (png_ptr->offset_table_ptr == NULL)
187
png_error(png_ptr, "Out Of memory.");
190
hptr = (png_byte huge *)table;
191
if ((png_size_t)hptr & 0xf)
193
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
194
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
196
for (i = 0; i < num_blocks; i++)
198
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
199
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
202
png_ptr->offset_table_number = num_blocks;
203
png_ptr->offset_table_count = 0;
204
png_ptr->offset_table_count_free = 0;
208
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
209
png_error(png_ptr, "Out of Memory.");
211
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
214
ret = farmalloc(size);
218
png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
224
/* free a pointer allocated by png_malloc(). In the default
225
configuration, png_ptr is not used, but is passed in case it
226
is needed. If ptr is NULL, return without taking any action. */
228
png_free(png_structp png_ptr, png_voidp ptr)
230
if (png_ptr == NULL || ptr == NULL)
233
#ifdef PNG_USER_MEM_SUPPORTED
234
if (png_ptr->free_fn != NULL)
236
(*(png_ptr->free_fn))(png_ptr, ptr);
239
else png_free_default(png_ptr, ptr);
243
png_free_default(png_structp png_ptr, png_voidp ptr)
245
#endif /* PNG_USER_MEM_SUPPORTED */
247
if (png_ptr->offset_table != NULL)
251
for (i = 0; i < png_ptr->offset_table_count; i++)
253
if (ptr == png_ptr->offset_table_ptr[i])
256
png_ptr->offset_table_count_free++;
260
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
262
farfree(png_ptr->offset_table);
263
farfree(png_ptr->offset_table_ptr);
264
png_ptr->offset_table = NULL;
265
png_ptr->offset_table_ptr = NULL;
275
#else /* Not the Borland DOS special memory handler */
277
/* Allocate memory for a png_struct or a png_info. The malloc and
278
memset can be replaced by a single call to calloc() if this is thought
279
to improve performance noticably.*/
280
png_voidp /* PRIVATE */
281
png_create_struct(int type)
283
#ifdef PNG_USER_MEM_SUPPORTED
284
return (png_create_struct_2(type, NULL));
287
/* Allocate memory for a png_struct or a png_info. The malloc and
288
memset can be replaced by a single call to calloc() if this is thought
289
to improve performance noticably.*/
290
png_voidp /* PRIVATE */
291
png_create_struct_2(int type, png_malloc_ptr malloc_fn)
293
#endif /* PNG_USER_MEM_SUPPORTED */
295
png_voidp struct_ptr;
297
if (type == PNG_STRUCT_INFO)
298
size = sizeof(png_info);
299
else if (type == PNG_STRUCT_PNG)
300
size = sizeof(png_struct);
302
return ((png_voidp)NULL);
304
#ifdef PNG_USER_MEM_SUPPORTED
305
if(malloc_fn != NULL)
307
if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
308
png_memset(struct_ptr, 0, size);
311
#endif /* PNG_USER_MEM_SUPPORTED */
313
#if defined(__TURBOC__) && !defined(__FLAT__)
314
if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
316
# if defined(_MSC_VER) && defined(MAXSEG_64K)
317
if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
319
if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
323
png_memset(struct_ptr, 0, size);
330
/* Free memory allocated by a png_create_struct() call */
332
png_destroy_struct(png_voidp struct_ptr)
334
#ifdef PNG_USER_MEM_SUPPORTED
335
png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
338
/* Free memory allocated by a png_create_struct() call */
340
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
342
#endif /* PNG_USER_MEM_SUPPORTED */
343
if (struct_ptr != NULL)
345
#ifdef PNG_USER_MEM_SUPPORTED
348
png_struct dummy_struct;
349
png_structp png_ptr = &dummy_struct;
350
(*(free_fn))(png_ptr, struct_ptr);
353
#endif /* PNG_USER_MEM_SUPPORTED */
354
#if defined(__TURBOC__) && !defined(__FLAT__)
357
# if defined(_MSC_VER) && defined(MAXSEG_64K)
367
/* Allocate memory. For reasonable files, size should never exceed
368
64K. However, zlib may allocate more then 64K if you don't tell
369
it not to. See zconf.h and png.h for more information. zlib does
370
need to allocate exactly 64K, so whatever you call here must
371
have the ability to do that. */
374
png_malloc(png_structp png_ptr, png_uint_32 size)
376
#ifndef PNG_USER_MEM_SUPPORTED
379
if (png_ptr == NULL || size == 0)
380
return ((png_voidp)NULL);
382
#ifdef PNG_USER_MEM_SUPPORTED
383
if(png_ptr->malloc_fn != NULL)
384
return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
386
return (png_malloc_default(png_ptr, size));
388
png_voidp /* PRIVATE */
389
png_malloc_default(png_structp png_ptr, png_uint_32 size)
392
#endif /* PNG_USER_MEM_SUPPORTED */
394
#ifdef PNG_MAX_MALLOC_64K
395
if (size > (png_uint_32)65536L)
396
png_error(png_ptr, "Cannot Allocate > 64K");
399
#if defined(__TURBOC__) && !defined(__FLAT__)
400
ret = farmalloc(size);
402
# if defined(_MSC_VER) && defined(MAXSEG_64K)
403
ret = halloc(size, 1);
405
ret = malloc((size_t)size);
411
png_error(png_ptr, "Out of Memory");
417
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
418
without taking any action. */
420
png_free(png_structp png_ptr, png_voidp ptr)
422
if (png_ptr == NULL || ptr == NULL)
425
#ifdef PNG_USER_MEM_SUPPORTED
426
if (png_ptr->free_fn != NULL)
428
(*(png_ptr->free_fn))(png_ptr, ptr);
431
else png_free_default(png_ptr, ptr);
434
png_free_default(png_structp png_ptr, png_voidp ptr)
436
if (png_ptr == NULL || ptr == NULL)
439
#endif /* PNG_USER_MEM_SUPPORTED */
441
#if defined(__TURBOC__) && !defined(__FLAT__)
444
# if defined(_MSC_VER) && defined(MAXSEG_64K)
452
#endif /* Not Borland DOS special memory handler */
454
png_voidp /* PRIVATE */
455
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
460
size = (png_size_t)length;
461
if ((png_uint_32)size != length)
462
png_error(png_ptr,"Overflow in png_memcpy_check.");
464
return(png_memcpy (s1, s2, size));
467
png_voidp /* PRIVATE */
468
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
473
size = (png_size_t)length;
474
if ((png_uint_32)size != length)
475
png_error(png_ptr,"Overflow in png_memset_check.");
477
return (png_memset (s1, value, size));
481
#ifdef PNG_USER_MEM_SUPPORTED
482
/* This function is called when the application wants to use another method
483
* of allocating and freeing memory.
486
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
487
malloc_fn, png_free_ptr free_fn)
489
png_ptr->mem_ptr = mem_ptr;
490
png_ptr->malloc_fn = malloc_fn;
491
png_ptr->free_fn = free_fn;
494
/* This function returns a pointer to the mem_ptr associated with the user
495
* functions. The application should free any memory associated with this
496
* pointer before png_write_destroy and png_read_destroy are called.
499
png_get_mem_ptr(png_structp png_ptr)
501
return ((png_voidp)png_ptr->mem_ptr);
503
#endif /* PNG_USER_MEM_SUPPORTED */