2
/* pngmem.c - stub functions for memory allocation
4
* libpng version 1.2.7 - September 12, 2004
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998-2004 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, png_malloc_ptr_NULL, png_voidp_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, png_voidp mem_ptr)
37
#endif /* PNG_USER_MEM_SUPPORTED */
41
if (type == PNG_STRUCT_INFO)
42
size = png_sizeof(png_info);
43
else if (type == PNG_STRUCT_PNG)
44
size = png_sizeof(png_struct);
46
return (png_get_copyright(NULL));
48
#ifdef PNG_USER_MEM_SUPPORTED
51
png_struct dummy_struct;
52
png_structp png_ptr = &dummy_struct;
53
png_ptr->mem_ptr=mem_ptr;
54
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
57
#endif /* PNG_USER_MEM_SUPPORTED */
58
struct_ptr = (png_voidp)farmalloc(size);
59
if (struct_ptr != NULL)
60
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, png_voidp_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,
78
if (struct_ptr != NULL)
80
#ifdef PNG_USER_MEM_SUPPORTED
83
png_struct dummy_struct;
84
png_structp png_ptr = &dummy_struct;
85
png_ptr->mem_ptr=mem_ptr;
86
(*(free_fn))(png_ptr, struct_ptr);
89
#endif /* PNG_USER_MEM_SUPPORTED */
94
/* Allocate memory. For reasonable files, size should never exceed
95
* 64K. However, zlib may allocate more then 64K if you don't tell
96
* it not to. See zconf.h and png.h for more information. zlib does
97
* need to allocate exactly 64K, so whatever you call here must
98
* have the ability to do that.
100
* Borland seems to have a problem in DOS mode for exactly 64K.
101
* It gives you a segment with an offset of 8 (perhaps to store its
102
* memory stuff). zlib doesn't like this at all, so we have to
103
* detect and deal with it. This code should not be needed in
104
* Windows or OS/2 modes, and only in 16 bit mode. This code has
105
* been updated by Alexander Lehmann for version 0.89 to waste less
108
* Note that we can't use png_size_t for the "size" declaration,
109
* since on some systems a png_size_t is a 16-bit quantity, and as a
110
* result, we would be truncating potentially larger memory requests
111
* (which should cause a fatal error) and introducing major problems.
115
png_malloc(png_structp png_ptr, png_uint_32 size)
119
if (png_ptr == NULL || size == 0)
122
#ifdef PNG_USER_MEM_SUPPORTED
123
if(png_ptr->malloc_fn != NULL)
124
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
126
ret = (png_malloc_default(png_ptr, size));
127
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
128
png_error(png_ptr, "Out of memory!");
133
png_malloc_default(png_structp png_ptr, png_uint_32 size)
136
#endif /* PNG_USER_MEM_SUPPORTED */
138
#ifdef PNG_MAX_MALLOC_64K
139
if (size > (png_uint_32)65536L)
141
png_warning(png_ptr, "Cannot Allocate > 64K");
147
if (size != (size_t)size)
149
else if (size == (png_uint_32)65536L)
151
if (png_ptr->offset_table == NULL)
153
/* try to see if we need to do any of this fancy stuff */
154
ret = farmalloc(size);
155
if (ret == NULL || ((png_size_t)ret & 0xffff))
158
png_uint_32 total_size;
161
png_byte huge * hptr;
169
if(png_ptr->zlib_window_bits > 14)
170
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
173
if (png_ptr->zlib_mem_level >= 7)
174
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
178
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
180
table = farmalloc(total_size);
184
#ifndef PNG_USER_MEM_SUPPORTED
185
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
186
png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
188
png_warning(png_ptr, "Out Of Memory.");
193
if ((png_size_t)table & 0xfff0)
195
#ifndef PNG_USER_MEM_SUPPORTED
196
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
198
"Farmalloc didn't return normalized pointer");
201
"Farmalloc didn't return normalized pointer");
206
png_ptr->offset_table = table;
207
png_ptr->offset_table_ptr = farmalloc(num_blocks *
208
png_sizeof (png_bytep));
210
if (png_ptr->offset_table_ptr == NULL)
212
#ifndef PNG_USER_MEM_SUPPORTED
213
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
214
png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
216
png_warning(png_ptr, "Out Of memory.");
221
hptr = (png_byte huge *)table;
222
if ((png_size_t)hptr & 0xf)
224
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
225
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
227
for (i = 0; i < num_blocks; i++)
229
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
230
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
233
png_ptr->offset_table_number = num_blocks;
234
png_ptr->offset_table_count = 0;
235
png_ptr->offset_table_count_free = 0;
239
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
241
#ifndef PNG_USER_MEM_SUPPORTED
242
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
243
png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
245
png_warning(png_ptr, "Out of Memory.");
250
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
253
ret = farmalloc(size);
255
#ifndef PNG_USER_MEM_SUPPORTED
258
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
259
png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
261
png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
268
/* free a pointer allocated by png_malloc(). In the default
269
configuration, png_ptr is not used, but is passed in case it
270
is needed. If ptr is NULL, return without taking any action. */
272
png_free(png_structp png_ptr, png_voidp ptr)
274
if (png_ptr == NULL || ptr == NULL)
277
#ifdef PNG_USER_MEM_SUPPORTED
278
if (png_ptr->free_fn != NULL)
280
(*(png_ptr->free_fn))(png_ptr, ptr);
283
else png_free_default(png_ptr, ptr);
287
png_free_default(png_structp png_ptr, png_voidp ptr)
289
#endif /* PNG_USER_MEM_SUPPORTED */
291
if (png_ptr->offset_table != NULL)
295
for (i = 0; i < png_ptr->offset_table_count; i++)
297
if (ptr == png_ptr->offset_table_ptr[i])
300
png_ptr->offset_table_count_free++;
304
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
306
farfree(png_ptr->offset_table);
307
farfree(png_ptr->offset_table_ptr);
308
png_ptr->offset_table = NULL;
309
png_ptr->offset_table_ptr = NULL;
319
#else /* Not the Borland DOS special memory handler */
321
/* Allocate memory for a png_struct or a png_info. The malloc and
322
memset can be replaced by a single call to calloc() if this is thought
323
to improve performance noticably. */
324
png_voidp /* PRIVATE */
325
png_create_struct(int type)
327
#ifdef PNG_USER_MEM_SUPPORTED
328
return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
331
/* Allocate memory for a png_struct or a png_info. The malloc and
332
memset can be replaced by a single call to calloc() if this is thought
333
to improve performance noticably. */
334
png_voidp /* PRIVATE */
335
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
337
#endif /* PNG_USER_MEM_SUPPORTED */
339
png_voidp struct_ptr;
341
if (type == PNG_STRUCT_INFO)
342
size = png_sizeof(png_info);
343
else if (type == PNG_STRUCT_PNG)
344
size = png_sizeof(png_struct);
348
#ifdef PNG_USER_MEM_SUPPORTED
349
if(malloc_fn != NULL)
351
png_struct dummy_struct;
352
png_structp png_ptr = &dummy_struct;
353
png_ptr->mem_ptr=mem_ptr;
354
struct_ptr = (*(malloc_fn))(png_ptr, size);
355
if (struct_ptr != NULL)
356
png_memset(struct_ptr, 0, size);
359
#endif /* PNG_USER_MEM_SUPPORTED */
361
#if defined(__TURBOC__) && !defined(__FLAT__)
362
struct_ptr = (png_voidp)farmalloc(size);
364
# if defined(_MSC_VER) && defined(MAXSEG_64K)
365
struct_ptr = (png_voidp)halloc(size,1);
367
struct_ptr = (png_voidp)malloc(size);
370
if (struct_ptr != NULL)
371
png_memset(struct_ptr, 0, size);
377
/* Free memory allocated by a png_create_struct() call */
379
png_destroy_struct(png_voidp struct_ptr)
381
#ifdef PNG_USER_MEM_SUPPORTED
382
png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
385
/* Free memory allocated by a png_create_struct() call */
387
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
390
#endif /* PNG_USER_MEM_SUPPORTED */
391
if (struct_ptr != NULL)
393
#ifdef PNG_USER_MEM_SUPPORTED
396
png_struct dummy_struct;
397
png_structp png_ptr = &dummy_struct;
398
png_ptr->mem_ptr=mem_ptr;
399
(*(free_fn))(png_ptr, struct_ptr);
402
#endif /* PNG_USER_MEM_SUPPORTED */
403
#if defined(__TURBOC__) && !defined(__FLAT__)
406
# if defined(_MSC_VER) && defined(MAXSEG_64K)
415
/* Allocate memory. For reasonable files, size should never exceed
416
64K. However, zlib may allocate more then 64K if you don't tell
417
it not to. See zconf.h and png.h for more information. zlib does
418
need to allocate exactly 64K, so whatever you call here must
419
have the ability to do that. */
422
png_malloc(png_structp png_ptr, png_uint_32 size)
426
#ifdef PNG_USER_MEM_SUPPORTED
427
if (png_ptr == NULL || size == 0)
430
if(png_ptr->malloc_fn != NULL)
431
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
433
ret = (png_malloc_default(png_ptr, size));
434
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
435
png_error(png_ptr, "Out of Memory!");
440
png_malloc_default(png_structp png_ptr, png_uint_32 size)
443
#endif /* PNG_USER_MEM_SUPPORTED */
445
if (png_ptr == NULL || size == 0)
448
#ifdef PNG_MAX_MALLOC_64K
449
if (size > (png_uint_32)65536L)
451
#ifndef PNG_USER_MEM_SUPPORTED
452
if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
453
png_error(png_ptr, "Cannot Allocate > 64K");
460
/* Check for overflow */
461
#if defined(__TURBOC__) && !defined(__FLAT__)
462
if (size != (unsigned long)size)
465
ret = farmalloc(size);
467
# if defined(_MSC_VER) && defined(MAXSEG_64K)
468
if (size != (unsigned long)size)
471
ret = halloc(size, 1);
473
if (size != (size_t)size)
476
ret = malloc((size_t)size);
480
#ifndef PNG_USER_MEM_SUPPORTED
481
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
482
png_error(png_ptr, "Out of Memory");
488
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
489
without taking any action. */
491
png_free(png_structp png_ptr, png_voidp ptr)
493
if (png_ptr == NULL || ptr == NULL)
496
#ifdef PNG_USER_MEM_SUPPORTED
497
if (png_ptr->free_fn != NULL)
499
(*(png_ptr->free_fn))(png_ptr, ptr);
502
else png_free_default(png_ptr, ptr);
505
png_free_default(png_structp png_ptr, png_voidp ptr)
507
if (png_ptr == NULL || ptr == NULL)
510
#endif /* PNG_USER_MEM_SUPPORTED */
512
#if defined(__TURBOC__) && !defined(__FLAT__)
515
# if defined(_MSC_VER) && defined(MAXSEG_64K)
523
#endif /* Not Borland DOS special memory handler */
525
#if defined(PNG_1_0_X)
526
# define png_malloc_warn png_malloc
528
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
529
* function will set up png_malloc() to issue a png_warning and return NULL
530
* instead of issuing a png_error, if it fails to allocate the requested
534
png_malloc_warn(png_structp png_ptr, png_uint_32 size)
537
png_uint_32 save_flags=png_ptr->flags;
539
png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
540
ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
541
png_ptr->flags=save_flags;
547
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
552
size = (png_size_t)length;
553
if ((png_uint_32)size != length)
554
png_error(png_ptr,"Overflow in png_memcpy_check.");
556
return(png_memcpy (s1, s2, size));
560
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
565
size = (png_size_t)length;
566
if ((png_uint_32)size != length)
567
png_error(png_ptr,"Overflow in png_memset_check.");
569
return (png_memset (s1, value, size));
573
#ifdef PNG_USER_MEM_SUPPORTED
574
/* This function is called when the application wants to use another method
575
* of allocating and freeing memory.
578
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
579
malloc_fn, png_free_ptr free_fn)
581
png_ptr->mem_ptr = mem_ptr;
582
png_ptr->malloc_fn = malloc_fn;
583
png_ptr->free_fn = free_fn;
586
/* This function returns a pointer to the mem_ptr associated with the user
587
* functions. The application should free any memory associated with this
588
* pointer before png_write_destroy and png_read_destroy are called.
591
png_get_mem_ptr(png_structp png_ptr)
593
return ((png_voidp)png_ptr->mem_ptr);
595
#endif /* PNG_USER_MEM_SUPPORTED */