blob: 88a6319c7cce06b4a37b26b5153077c6714e41aa [file] [log] [blame]
Guy Schalnat0d580581995-07-20 02:43:20 -05001
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-Pehrson2687fcc1998-01-07 20:54:20 -06004 * libpng 0.97
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
Glenn Randers-Pehrson2687fcc1998-01-07 20:54:20 -06008 * Copyright (c) 1998, Glenn Randers-Pehrson
9 * January 7, 1998
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060010 *
11 * This file provides a location for all memory allocation. Users which
12 * need special memory handling are expected to modify the code in this file
13 * to meet their needs. See the instructions at each function.
14 */
Guy Schalnat0d580581995-07-20 02:43:20 -050015
16#define PNG_INTERNAL
17#include "png.h"
18
Guy Schalnat4ee97b01996-01-16 01:51:56 -060019/* Borland DOS special memory handler */
20#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
21/* if you change this, be sure to change the one in png.h also */
22
Guy Schalnate5a37791996-06-05 15:50:50 -050023/* Allocate memory for a png_struct. The malloc and memset can be replaced
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060024 by a single call to calloc() if this is thought to improve performance. */
Guy Schalnate5a37791996-06-05 15:50:50 -050025png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060026png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -050027{
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060028 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -050029 png_voidp struct_ptr;
30
31 if (type == PNG_STRUCT_INFO)
32 size = sizeof(png_info);
33 else if (type == PNG_STRUCT_PNG)
34 size = sizeof(png_struct);
35 else
36 return (png_voidp)NULL;
37
38 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
39 {
40 png_memset(struct_ptr, 0, size);
41 }
42
43 return (struct_ptr);
44}
45
46
47/* Free memory allocated by a png_create_struct() call */
48void
49png_destroy_struct(png_voidp struct_ptr)
50{
Andreas Dilger47a0c421997-05-16 02:46:07 -050051 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -050052 farfree (struct_ptr);
53}
54
Guy Schalnat0d580581995-07-20 02:43:20 -050055/* Allocate memory. For reasonable files, size should never exceed
Andreas Dilger47a0c421997-05-16 02:46:07 -050056 * 64K. However, zlib may allocate more then 64K if you don't tell
57 * it not to. See zconf.h and png.h for more information. zlib does
58 * need to allocate exactly 64K, so whatever you call here must
59 * have the ability to do that.
60 *
61 * Borland seems to have a problem in DOS mode for exactly 64K.
62 * It gives you a segment with an offset of 8 (perhaps to store it's
63 * memory stuff). zlib doesn't like this at all, so we have to
64 * detect and deal with it. This code should not be needed in
65 * Windows or OS/2 modes, and only in 16 bit mode. This code has
66 * been updated by Alexander Lehmann for version 0.89 to waste less
67 * memory.
68 *
69 * Note that we can't use png_size_t for the "size" declaration,
70 * since on some systems a png_size_t is a 16-bit quantity, and as a
71 * result, we would be truncating potentially larger memory requests
72 * (which should cause a fatal error) and introducing major problems.
73 */
Guy Schalnat4ee97b01996-01-16 01:51:56 -060074png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060075png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnat4ee97b01996-01-16 01:51:56 -060076{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060077 png_voidp ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -050078 if (png_ptr == NULL || size == 0)
Guy Schalnate5a37791996-06-05 15:50:50 -050079 return ((voidp)NULL);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060080
81#ifdef PNG_MAX_MALLOC_64K
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060082 if (size > (png_uint_32)65536L)
83 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat4ee97b01996-01-16 01:51:56 -060084#endif
85
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060086 if (size == (png_uint_32)65536L)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060087 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050088 if (png_ptr->offset_table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060089 {
90 /* try to see if we need to do any of this fancy stuff */
91 ret = farmalloc(size);
Andreas Dilger47a0c421997-05-16 02:46:07 -050092 if (ret == NULL || ((png_size_t)ret & 0xffff))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060093 {
94 int num_blocks;
95 png_uint_32 total_size;
96 png_bytep table;
97 int i;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060098 png_byte huge * hptr;
99
Andreas Dilger47a0c421997-05-16 02:46:07 -0500100 if (ret != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600101 farfree(ret);
Guy Schalnate5a37791996-06-05 15:50:50 -0500102 ret = NULL;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600103
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600104 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
105 if (num_blocks < 1)
106 num_blocks = 1;
107 if (png_ptr->zlib_mem_level >= 7)
108 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
109 else
110 num_blocks++;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600111
Guy Schalnate5a37791996-06-05 15:50:50 -0500112 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600113
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600114 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600115
Andreas Dilger47a0c421997-05-16 02:46:07 -0500116 if (table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600117 {
118 png_error(png_ptr, "Out of Memory");
119 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600120
Andreas Dilger47a0c421997-05-16 02:46:07 -0500121 if ((png_size_t)table & 0xfff0)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600122 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500123 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600124 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600125
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600126 png_ptr->offset_table = table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500127 png_ptr->offset_table_ptr = farmalloc(num_blocks *
128 sizeof (png_bytep));
Guy Schalnate5a37791996-06-05 15:50:50 -0500129
Andreas Dilger47a0c421997-05-16 02:46:07 -0500130 if (png_ptr->offset_table_ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600131 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500132 png_error(png_ptr, "Out of memory");
133 }
134
135 hptr = (png_byte huge *)table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500136 if ((png_size_t)hptr & 0xf)
Guy Schalnate5a37791996-06-05 15:50:50 -0500137 {
138 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
139 hptr += 16L;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600140 }
141 for (i = 0; i < num_blocks; i++)
142 {
143 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600144 hptr += (png_uint_32)65536L;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600145 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600146
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600147 png_ptr->offset_table_number = num_blocks;
148 png_ptr->offset_table_count = 0;
149 png_ptr->offset_table_count_free = 0;
150 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600151 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500152
153 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
154 png_error(png_ptr, "Out of Memory");
155
156 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600157 }
158 else
159 ret = farmalloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500160
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500161 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500162 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600163 png_error(png_ptr, "Out of Memory");
Guy Schalnat0d580581995-07-20 02:43:20 -0500164 }
165
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600166 return ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500167}
168
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600169/* free a pointer allocated by png_malloc(). In the default
170 configuration, png_ptr is not used, but is passed in case it
171 is needed. If ptr is NULL, return without taking any action. */
Guy Schalnat0d580581995-07-20 02:43:20 -0500172void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600173png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500174{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500175 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600176 return;
177
Andreas Dilger47a0c421997-05-16 02:46:07 -0500178 if (png_ptr->offset_table != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600179 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500180 int i;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600181
Andreas Dilger47a0c421997-05-16 02:46:07 -0500182 for (i = 0; i < png_ptr->offset_table_count; i++)
183 {
184 if (ptr == png_ptr->offset_table_ptr[i])
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600185 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500186 ptr = NULL;
187 png_ptr->offset_table_count_free++;
188 break;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600189 }
190 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500191 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
192 {
193 farfree(png_ptr->offset_table);
194 farfree(png_ptr->offset_table_ptr);
195 png_ptr->offset_table = NULL;
196 png_ptr->offset_table_ptr = NULL;
197 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600198 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500199
200 if (ptr != NULL)
201 farfree(ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600202}
203
204#else /* Not the Borland DOS special memory handler */
205
Guy Schalnate5a37791996-06-05 15:50:50 -0500206/* Allocate memory for a png_struct or a png_info. The malloc and
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600207 memset can be replaced by a single call to calloc() if this is thought
208 to improve performance noticably.*/
Guy Schalnate5a37791996-06-05 15:50:50 -0500209png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600210png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -0500211{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500212 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -0500213 png_voidp struct_ptr;
214
215 if (type == PNG_STRUCT_INFO)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500216 size = sizeof(png_info);
Guy Schalnate5a37791996-06-05 15:50:50 -0500217 else if (type == PNG_STRUCT_PNG)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500218 size = sizeof(png_struct);
Guy Schalnate5a37791996-06-05 15:50:50 -0500219 else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500220 return (png_voidp)NULL;
Guy Schalnate5a37791996-06-05 15:50:50 -0500221
222#if defined(__TURBOC__) && !defined(__FLAT__)
223 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
224#else
225# if defined(_MSC_VER) && defined(MAXSEG_64K)
Guy Schalnatc21f90c1996-06-17 16:24:45 -0500226 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500227# else
228 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
229# endif
230#endif
231 {
232 png_memset(struct_ptr, 0, size);
233 }
234
235 return (struct_ptr);
236}
237
238
239/* Free memory allocated by a png_create_struct() call */
240void
241png_destroy_struct(png_voidp struct_ptr)
242{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500243 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500244#if defined(__TURBOC__) && !defined(__FLAT__)
245 farfree(struct_ptr);
246#else
247# if defined(_MSC_VER) && defined(MAXSEG_64K)
248 hfree(struct_ptr);
249# else
250 free(struct_ptr);
251# endif
252#endif
253}
254
255
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600256/* Allocate memory. For reasonable files, size should never exceed
257 64K. However, zlib may allocate more then 64K if you don't tell
Andreas Dilger47a0c421997-05-16 02:46:07 -0500258 it not to. See zconf.h and png.h for more information. zlib does
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600259 need to allocate exactly 64K, so whatever you call here must
260 have the ability to do that. */
261
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600262png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600263png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600264{
265 png_voidp ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500266 if (png_ptr == NULL || size == 0)
267 return (NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600268
269#ifdef PNG_MAX_MALLOC_64K
270 if (size > (png_uint_32)65536L)
271 png_error(png_ptr, "Cannot Allocate > 64K");
272#endif
273
274#if defined(__TURBOC__) && !defined(__FLAT__)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500275 ret = farmalloc((png_size_t)size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600276#else
277# if defined(_MSC_VER) && defined(MAXSEG_64K)
278 ret = halloc(size, 1);
279# else
280 ret = malloc(size);
281# endif
282#endif
283
284 if (ret == NULL)
285 {
286 png_error(png_ptr, "Out of Memory");
287 }
288
289 return ret;
290}
291
Andreas Dilger47a0c421997-05-16 02:46:07 -0500292/* Free a pointer allocated by png_malloc(). In the default
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600293 configuration, png_ptr is not used, but is passed in case it
294 is needed. If ptr is NULL, return without taking any action. */
295void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600296png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600297{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500298 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600299 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500300
Guy Schalnat6d764711995-12-19 03:22:19 -0600301#if defined(__TURBOC__) && !defined(__FLAT__)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500302 farfree(ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500303#else
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600304# if defined(_MSC_VER) && defined(MAXSEG_64K)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500305 hfree(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600306# else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500307 free(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600308# endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500309#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500310}
311
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600312#endif /* Not Borland DOS special memory handler */
Guy Schalnat6d764711995-12-19 03:22:19 -0600313