blob: 81779a3cf7eaac3e4ffeb7b956afb2b01854e7ca [file] [log] [blame]
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001
Guy Schalnat0f716451995-11-28 11:22:13 -06002/* pngmem.c - stub functions for memory allocation
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -06004 * Last changed in libpng 1.4.0 November 14, 2006
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -06006 * Copyright (c) 1998-2006 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05007 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06009 *
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -050010 * This file provides a location for all memory allocation. Users who
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -050011 * 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.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060015 */
Guy Schalnat0d580581995-07-20 02:43:20 -050016
Guy Schalnat0d580581995-07-20 02:43:20 -050017#include "png.h"
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050018#include "pngpriv.h"
Guy Schalnat0d580581995-07-20 02:43:20 -050019
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -060020#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
21
Guy Schalnat4ee97b01996-01-16 01:51:56 -060022/* Borland DOS special memory handler */
23#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
24/* if you change this, be sure to change the one in png.h also */
25
Guy Schalnate5a37791996-06-05 15:50:50 -050026/* Allocate memory for a png_struct. The malloc and memset can be replaced
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060027 by a single call to calloc() if this is thought to improve performance. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050028png_voidp /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060029png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -050030{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050031#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050032 return (png_create_struct_2(type, NULL, NULL));
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050033}
34
35/* Alternate version of png_create_struct, for use with user-defined malloc. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050036png_voidp /* PRIVATE */
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -050037png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050038{
39#endif /* PNG_USER_MEM_SUPPORTED */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060040 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -050041 png_voidp struct_ptr;
42
43 if (type == PNG_STRUCT_INFO)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050044 size = sizeof(png_info);
Guy Schalnate5a37791996-06-05 15:50:50 -050045 else if (type == PNG_STRUCT_PNG)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050046 size = sizeof(png_struct);
Guy Schalnate5a37791996-06-05 15:50:50 -050047 else
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -050048 return (png_get_copyright(NULL));
Guy Schalnate5a37791996-06-05 15:50:50 -050049
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050050#ifdef PNG_USER_MEM_SUPPORTED
51 if(malloc_fn != NULL)
52 {
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -050053 png_struct dummy_struct;
54 png_structp png_ptr = &dummy_struct;
55 png_ptr->mem_ptr=mem_ptr;
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050056 struct_ptr = (*(malloc_fn))(png_ptr, size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050057 }
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -050058 else
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050059#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -050060 struct_ptr = (png_voidp)farmalloc(size);
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -050061 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -050062 png_memset(struct_ptr, 0, size);
Guy Schalnate5a37791996-06-05 15:50:50 -050063 return (struct_ptr);
64}
65
Guy Schalnate5a37791996-06-05 15:50:50 -050066/* Free memory allocated by a png_create_struct() call */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050067void /* PRIVATE */
Guy Schalnate5a37791996-06-05 15:50:50 -050068png_destroy_struct(png_voidp struct_ptr)
69{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050070#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050071 png_destroy_struct_2(struct_ptr, NULL, NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050072}
73
74/* Free memory allocated by a png_create_struct() call */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050075void /* PRIVATE */
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -050076png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
77 png_voidp mem_ptr)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050078{
79#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -050080 if (struct_ptr != NULL)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060081 {
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050082#ifdef PNG_USER_MEM_SUPPORTED
83 if(free_fn != NULL)
84 {
85 png_struct dummy_struct;
86 png_structp png_ptr = &dummy_struct;
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -050087 png_ptr->mem_ptr=mem_ptr;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050088 (*(free_fn))(png_ptr, struct_ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -050089 return;
90 }
91#endif /* PNG_USER_MEM_SUPPORTED */
Guy Schalnate5a37791996-06-05 15:50:50 -050092 farfree (struct_ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -060093 }
Guy Schalnate5a37791996-06-05 15:50:50 -050094}
95
Guy Schalnat0d580581995-07-20 02:43:20 -050096/* Allocate memory. For reasonable files, size should never exceed
Andreas Dilger47a0c421997-05-16 02:46:07 -050097 * 64K. However, zlib may allocate more then 64K if you don't tell
98 * it not to. See zconf.h and png.h for more information. zlib does
99 * need to allocate exactly 64K, so whatever you call here must
100 * have the ability to do that.
101 *
102 * Borland seems to have a problem in DOS mode for exactly 64K.
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -0500103 * It gives you a segment with an offset of 8 (perhaps to store its
Andreas Dilger47a0c421997-05-16 02:46:07 -0500104 * memory stuff). zlib doesn't like this at all, so we have to
105 * detect and deal with it. This code should not be needed in
106 * Windows or OS/2 modes, and only in 16 bit mode. This code has
107 * been updated by Alexander Lehmann for version 0.89 to waste less
108 * memory.
109 *
110 * Note that we can't use png_size_t for the "size" declaration,
111 * since on some systems a png_size_t is a 16-bit quantity, and as a
112 * result, we would be truncating potentially larger memory requests
113 * (which should cause a fatal error) and introducing major problems.
114 */
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500115
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500116png_voidp PNGAPI
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500117png_malloc(png_structp png_ptr, png_alloc_size_t size)
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600118{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600119 png_voidp ret;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500120
Andreas Dilger47a0c421997-05-16 02:46:07 -0500121 if (png_ptr == NULL || size == 0)
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500122 return (NULL);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600123
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500124#ifdef PNG_USER_MEM_SUPPORTED
125 if(png_ptr->malloc_fn != NULL)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500126 ret = (*(png_ptr->malloc_fn))(png_ptr, size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500127 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500128 ret = png_malloc_default(png_ptr, size);
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500129 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
130 png_error(png_ptr, "Out of memory!");
131 return (ret);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500132}
133
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500134png_voidp PNGAPI
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500135png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500136{
137 png_voidp ret;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600138#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500139
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600140 if (png_ptr == NULL || size == 0)
141 return (NULL);
142
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600143#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500144 if (size > (png_alloc_size_t)65536L)
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500145 {
146 png_warning(png_ptr, "Cannot Allocate > 64K");
147 ret = NULL;
148 }
149 else
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600150#endif
151
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500152#if !defined(INT_MAX) || (INT_MAX <= 0x7ffffffeL)
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500153 if (size != (size_t)size)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500154 ret = NULL;
155 else
156#endif
157 if (size == (png_alloc_size_t)65536L)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600158 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500159 if (png_ptr->offset_table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600160 {
161 /* try to see if we need to do any of this fancy stuff */
162 ret = farmalloc(size);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500163 if (ret == NULL || ((png_size_t)ret & 0xffff))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600164 {
165 int num_blocks;
166 png_uint_32 total_size;
167 png_bytep table;
168 int i;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600169 png_byte huge * hptr;
170
Andreas Dilger47a0c421997-05-16 02:46:07 -0500171 if (ret != NULL)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600172 {
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600173 farfree(ret);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600174 ret = NULL;
175 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600176
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500177 if(png_ptr->zlib_window_bits > 14)
178 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
179 else
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600180 num_blocks = 1;
181 if (png_ptr->zlib_mem_level >= 7)
182 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
183 else
184 num_blocks++;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600185
Guy Schalnate5a37791996-06-05 15:50:50 -0500186 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600187
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600188 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600189
Andreas Dilger47a0c421997-05-16 02:46:07 -0500190 if (table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600191 {
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500192#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -0500193 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500194 png_error(png_ptr, "Out Of Memory"); /* Note "O" and "M" */
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600195 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500196 png_warning(png_ptr, "Out Of Memory");
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500197#endif
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600198 return (NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600199 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600200
Andreas Dilger47a0c421997-05-16 02:46:07 -0500201 if ((png_size_t)table & 0xfff0)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600202 {
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500203#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -0500204 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600205 png_error(png_ptr,
206 "Farmalloc didn't return normalized pointer");
207 else
208 png_warning(png_ptr,
209 "Farmalloc didn't return normalized pointer");
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500210#endif
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600211 return (NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600212 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600213
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600214 png_ptr->offset_table = table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500215 png_ptr->offset_table_ptr = farmalloc(num_blocks *
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500216 sizeof(png_bytep));
Guy Schalnate5a37791996-06-05 15:50:50 -0500217
Andreas Dilger47a0c421997-05-16 02:46:07 -0500218 if (png_ptr->offset_table_ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600219 {
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500220#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -0500221 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500222 png_error(png_ptr, "Out Of memory"); /* Note "O" and "M" */
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600223 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500224 png_warning(png_ptr, "Out Of memory");
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500225#endif
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600226 return (NULL);
Guy Schalnate5a37791996-06-05 15:50:50 -0500227 }
228
229 hptr = (png_byte huge *)table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500230 if ((png_size_t)hptr & 0xf)
Guy Schalnate5a37791996-06-05 15:50:50 -0500231 {
232 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500233 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600234 }
235 for (i = 0; i < num_blocks; i++)
236 {
237 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
Glenn Randers-Pehrson4393a9a1999-09-17 12:27:26 -0500238 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600239 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600240
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600241 png_ptr->offset_table_number = num_blocks;
242 png_ptr->offset_table_count = 0;
243 png_ptr->offset_table_count_free = 0;
244 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600245 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500246
247 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600248 {
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500249#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -0500250 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500251 png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600252 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500253 png_warning(png_ptr, "Out of Memory");
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500254#endif
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600255 return (NULL);
256 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500257
258 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600259 }
260 else
261 ret = farmalloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500262
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500263#ifndef PNG_USER_MEM_SUPPORTED
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500264 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500265 {
Glenn Randers-Pehrson5b5dcf82004-07-17 22:45:44 -0500266 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500267 png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600268 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500269 png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
Guy Schalnat0d580581995-07-20 02:43:20 -0500270 }
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500271#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500272
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600273 return (ret);
Guy Schalnat0d580581995-07-20 02:43:20 -0500274}
275
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500276/* free a pointer allocated by png_malloc(). In the default
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600277 configuration, png_ptr is not used, but is passed in case it
278 is needed. If ptr is NULL, return without taking any action. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500279void PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500280png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500281{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500282 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600283 return;
284
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500285#ifdef PNG_USER_MEM_SUPPORTED
286 if (png_ptr->free_fn != NULL)
287 {
288 (*(png_ptr->free_fn))(png_ptr, ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500289 return;
290 }
291 else png_free_default(png_ptr, ptr);
292}
293
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500294void PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500295png_free_default(png_structp png_ptr, png_voidp ptr)
296{
297#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600298
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600299 if(png_ptr == NULL) return;
300
Andreas Dilger47a0c421997-05-16 02:46:07 -0500301 if (png_ptr->offset_table != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600302 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500303 int i;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600304
Andreas Dilger47a0c421997-05-16 02:46:07 -0500305 for (i = 0; i < png_ptr->offset_table_count; i++)
306 {
307 if (ptr == png_ptr->offset_table_ptr[i])
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600308 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500309 ptr = NULL;
310 png_ptr->offset_table_count_free++;
311 break;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600312 }
313 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500314 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
315 {
316 farfree(png_ptr->offset_table);
317 farfree(png_ptr->offset_table_ptr);
318 png_ptr->offset_table = NULL;
319 png_ptr->offset_table_ptr = NULL;
320 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600321 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500322
323 if (ptr != NULL)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600324 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500325 farfree(ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600326 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600327}
328
329#else /* Not the Borland DOS special memory handler */
330
Guy Schalnate5a37791996-06-05 15:50:50 -0500331/* Allocate memory for a png_struct or a png_info. The malloc and
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600332 memset can be replaced by a single call to calloc() if this is thought
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500333 to improve performance noticably. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500334png_voidp /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600335png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -0500336{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500337#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500338 return (png_create_struct_2(type, NULL, NULL));
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500339}
340
341/* Allocate memory for a png_struct or a png_info. The malloc and
342 memset can be replaced by a single call to calloc() if this is thought
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500343 to improve performance noticably. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500344png_voidp /* PRIVATE */
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500345png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500346{
347#endif /* PNG_USER_MEM_SUPPORTED */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500348 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -0500349 png_voidp struct_ptr;
350
351 if (type == PNG_STRUCT_INFO)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500352 size = sizeof(png_info);
Guy Schalnate5a37791996-06-05 15:50:50 -0500353 else if (type == PNG_STRUCT_PNG)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500354 size = sizeof(png_struct);
Guy Schalnate5a37791996-06-05 15:50:50 -0500355 else
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500356 return (NULL);
Guy Schalnate5a37791996-06-05 15:50:50 -0500357
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500358#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500359 if (malloc_fn != NULL)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500360 {
Glenn Randers-Pehrson5cded0b2001-11-07 07:10:08 -0600361 png_struct dummy_struct;
362 png_structp png_ptr = &dummy_struct;
363 png_ptr->mem_ptr=mem_ptr;
Glenn Randers-Pehrsonae498dc2001-11-24 14:53:31 -0600364 struct_ptr = (*(malloc_fn))(png_ptr, size);
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500365 if (struct_ptr != NULL)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500366 png_memset(struct_ptr, 0, size);
367 return (struct_ptr);
368 }
369#endif /* PNG_USER_MEM_SUPPORTED */
370
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500371 struct_ptr = (png_voidp)png_mem_alloc(size);
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500372 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500373 png_memset(struct_ptr, 0, size);
Guy Schalnate5a37791996-06-05 15:50:50 -0500374
375 return (struct_ptr);
376}
377
378
379/* Free memory allocated by a png_create_struct() call */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500380void /* PRIVATE */
Guy Schalnate5a37791996-06-05 15:50:50 -0500381png_destroy_struct(png_voidp struct_ptr)
382{
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500383#ifdef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500384 png_destroy_struct_2(struct_ptr, NULL, NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500385}
386
387/* Free memory allocated by a png_create_struct() call */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500388void /* PRIVATE */
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500389png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
390 png_voidp mem_ptr)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500391{
392#endif /* PNG_USER_MEM_SUPPORTED */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500393 if (struct_ptr != NULL)
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600394 {
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500395#ifdef PNG_USER_MEM_SUPPORTED
396 if(free_fn != NULL)
397 {
398 png_struct dummy_struct;
399 png_structp png_ptr = &dummy_struct;
Glenn Randers-Pehrson8b6a8892001-05-18 04:54:50 -0500400 png_ptr->mem_ptr=mem_ptr;
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500401 (*(free_fn))(png_ptr, struct_ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500402 return;
403 }
404#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500405 png_mem_free(struct_ptr);
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -0600406 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500407}
408
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600409/* Allocate memory. For reasonable files, size should never exceed
410 64K. However, zlib may allocate more then 64K if you don't tell
Andreas Dilger47a0c421997-05-16 02:46:07 -0500411 it not to. See zconf.h and png.h for more information. zlib does
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600412 need to allocate exactly 64K, so whatever you call here must
413 have the ability to do that. */
414
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500415png_voidp PNGAPI
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500416png_malloc(png_structp png_ptr, png_alloc_size_t size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600417{
418 png_voidp ret;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500419
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500420#ifdef PNG_USER_MEM_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -0500421 if (png_ptr == NULL || size == 0)
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -0500422 return (NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600423
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500424 if (png_ptr->malloc_fn != NULL)
425 ret = (*(png_ptr->malloc_fn))(png_ptr, size);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500426 else
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500427 ret = png_malloc_default(png_ptr, size);
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500428 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
429 png_error(png_ptr, "Out of Memory!");
430 return (ret);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500431}
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500432
Glenn Randers-Pehrson73d57cb2002-03-25 18:49:08 -0600433png_voidp PNGAPI
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500434png_malloc_default(png_structp png_ptr, png_alloc_size_t size)
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500435{
436 png_voidp ret;
437#endif /* PNG_USER_MEM_SUPPORTED */
438
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500439 if (png_ptr == NULL || size == 0)
440 return (NULL);
441
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600442#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500443 if (size > (png_alloc_size_t)65536L)
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600444 {
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500445#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600446 if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
447 png_error(png_ptr, "Cannot Allocate > 64K");
448 else
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500449#endif
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600450 return NULL;
451 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600452#endif
453
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500454 ret = png_mem_alloc(size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600455
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500456#ifndef PNG_USER_MEM_SUPPORTED
Glenn Randers-Pehrson9c0f0942002-02-21 23:14:23 -0600457 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600458 png_error(png_ptr, "Out of Memory");
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500459#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600460
Glenn Randers-Pehrsonb2120021998-01-31 20:07:59 -0600461 return (ret);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600462}
463
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500464/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
465 without taking any action. */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500466void PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500467png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600468{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500469 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600470 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500471
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500472#ifdef PNG_USER_MEM_SUPPORTED
473 if (png_ptr->free_fn != NULL)
474 {
475 (*(png_ptr->free_fn))(png_ptr, ptr);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500476 return;
477 }
478 else png_free_default(png_ptr, ptr);
479}
Glenn Randers-Pehrson73d57cb2002-03-25 18:49:08 -0600480void PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500481png_free_default(png_structp png_ptr, png_voidp ptr)
482{
Glenn Randers-Pehrson6d8f3b01999-10-23 08:39:18 -0500483 if (png_ptr == NULL || ptr == NULL)
484 return;
485
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500486#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrson17218292006-04-20 07:20:46 -0500487 png_mem_free(ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500488}
489
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600490#endif /* Not Borland DOS special memory handler */
Guy Schalnat6d764711995-12-19 03:22:19 -0600491
Glenn Randers-Pehrson2ae022d2002-07-01 22:23:46 -0500492/* This function was added at libpng version 1.2.3. The png_malloc_warn()
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500493 * function will set up png_malloc() to issue a png_warning and return NULL
494 * instead of issuing a png_error, if it fails to allocate the requested
495 * memory.
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500496 */
497png_voidp PNGAPI
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500498png_malloc_warn(png_structp png_ptr, png_alloc_size_t size)
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500499{
500 png_voidp ptr;
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600501 if(png_ptr == NULL) return (NULL);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -0500502 png_uint_32 save_flags=png_ptr->flags;
503
504 png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
505 ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
506 png_ptr->flags=save_flags;
507 return(ptr);
508}
509
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500510#ifdef PNG_USER_MEM_SUPPORTED
511/* This function is called when the application wants to use another method
512 * of allocating and freeing memory.
513 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500514void PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500515png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
516 malloc_fn, png_free_ptr free_fn)
517{
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600518 if(png_ptr != NULL) {
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500519 png_ptr->mem_ptr = mem_ptr;
520 png_ptr->malloc_fn = malloc_fn;
521 png_ptr->free_fn = free_fn;
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600522 }
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500523}
524
525/* This function returns a pointer to the mem_ptr associated with the user
526 * functions. The application should free any memory associated with this
527 * pointer before png_write_destroy and png_read_destroy are called.
528 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500529png_voidp PNGAPI
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500530png_get_mem_ptr(png_structp png_ptr)
531{
Glenn Randers-Pehrson6b12c082006-11-14 10:53:30 -0600532 if(png_ptr == NULL) return (NULL);
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500533 return ((png_voidp)png_ptr->mem_ptr);
534}
535#endif /* PNG_USER_MEM_SUPPORTED */
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500536
Glenn Randers-Pehrson9c3ab682006-02-20 22:09:05 -0600537#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */