blob: fa649dae6e5c0a8154ae5982fd32ee034ca77369 [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 *
4 * libpng 1.00.97
5 * 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
8 * May 28, 1997
9 *
10 * This file provides a location for all memory allocation. Users which
11 * need special memory handling are expected to modify the code in this file
12 * to meet their needs. See the instructions at each function.
13 */
Guy Schalnat0d580581995-07-20 02:43:20 -050014
15#define PNG_INTERNAL
16#include "png.h"
17
Guy Schalnat4ee97b01996-01-16 01:51:56 -060018/* Borland DOS special memory handler */
19#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
20/* if you change this, be sure to change the one in png.h also */
21
Guy Schalnate5a37791996-06-05 15:50:50 -050022/* Allocate memory for a png_struct. The malloc and memset can be replaced
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060023 by a single call to calloc() if this is thought to improve performance. */
Guy Schalnate5a37791996-06-05 15:50:50 -050024png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060025png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -050026{
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060027 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -050028 png_voidp struct_ptr;
29
30 if (type == PNG_STRUCT_INFO)
31 size = sizeof(png_info);
32 else if (type == PNG_STRUCT_PNG)
33 size = sizeof(png_struct);
34 else
35 return (png_voidp)NULL;
36
37 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
38 {
39 png_memset(struct_ptr, 0, size);
40 }
41
42 return (struct_ptr);
43}
44
45
46/* Free memory allocated by a png_create_struct() call */
47void
48png_destroy_struct(png_voidp struct_ptr)
49{
Andreas Dilger47a0c421997-05-16 02:46:07 -050050 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -050051 farfree (struct_ptr);
52}
53
Guy Schalnat0d580581995-07-20 02:43:20 -050054/* Allocate memory. For reasonable files, size should never exceed
Andreas Dilger47a0c421997-05-16 02:46:07 -050055 * 64K. However, zlib may allocate more then 64K if you don't tell
56 * it not to. See zconf.h and png.h for more information. zlib does
57 * need to allocate exactly 64K, so whatever you call here must
58 * have the ability to do that.
59 *
60 * Borland seems to have a problem in DOS mode for exactly 64K.
61 * It gives you a segment with an offset of 8 (perhaps to store it's
62 * memory stuff). zlib doesn't like this at all, so we have to
63 * detect and deal with it. This code should not be needed in
64 * Windows or OS/2 modes, and only in 16 bit mode. This code has
65 * been updated by Alexander Lehmann for version 0.89 to waste less
66 * memory.
67 *
68 * Note that we can't use png_size_t for the "size" declaration,
69 * since on some systems a png_size_t is a 16-bit quantity, and as a
70 * result, we would be truncating potentially larger memory requests
71 * (which should cause a fatal error) and introducing major problems.
72 */
Guy Schalnat4ee97b01996-01-16 01:51:56 -060073png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060074png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnat4ee97b01996-01-16 01:51:56 -060075{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060076 png_voidp ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -050077 if (png_ptr == NULL || size == 0)
Guy Schalnate5a37791996-06-05 15:50:50 -050078 return ((voidp)NULL);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060079
80#ifdef PNG_MAX_MALLOC_64K
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060081 if (size > (png_uint_32)65536L)
82 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat4ee97b01996-01-16 01:51:56 -060083#endif
84
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060085 if (size == (png_uint_32)65536L)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060086 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050087 if (png_ptr->offset_table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060088 {
89 /* try to see if we need to do any of this fancy stuff */
90 ret = farmalloc(size);
Andreas Dilger47a0c421997-05-16 02:46:07 -050091 if (ret == NULL || ((png_size_t)ret & 0xffff))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060092 {
93 int num_blocks;
94 png_uint_32 total_size;
95 png_bytep table;
96 int i;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060097 png_byte huge * hptr;
98
Andreas Dilger47a0c421997-05-16 02:46:07 -050099 if (ret != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600100 farfree(ret);
Guy Schalnate5a37791996-06-05 15:50:50 -0500101 ret = NULL;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600102
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600103 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
104 if (num_blocks < 1)
105 num_blocks = 1;
106 if (png_ptr->zlib_mem_level >= 7)
107 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
108 else
109 num_blocks++;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600110
Guy Schalnate5a37791996-06-05 15:50:50 -0500111 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600112
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600113 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600114
Andreas Dilger47a0c421997-05-16 02:46:07 -0500115 if (table == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600116 {
117 png_error(png_ptr, "Out of Memory");
118 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600119
Andreas Dilger47a0c421997-05-16 02:46:07 -0500120 if ((png_size_t)table & 0xfff0)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600121 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500122 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600123 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600124
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600125 png_ptr->offset_table = table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500126 png_ptr->offset_table_ptr = farmalloc(num_blocks *
127 sizeof (png_bytep));
Guy Schalnate5a37791996-06-05 15:50:50 -0500128
Andreas Dilger47a0c421997-05-16 02:46:07 -0500129 if (png_ptr->offset_table_ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600130 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500131 png_error(png_ptr, "Out of memory");
132 }
133
134 hptr = (png_byte huge *)table;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500135 if ((png_size_t)hptr & 0xf)
Guy Schalnate5a37791996-06-05 15:50:50 -0500136 {
137 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
138 hptr += 16L;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600139 }
140 for (i = 0; i < num_blocks; i++)
141 {
142 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600143 hptr += (png_uint_32)65536L;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600144 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600145
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600146 png_ptr->offset_table_number = num_blocks;
147 png_ptr->offset_table_count = 0;
148 png_ptr->offset_table_count_free = 0;
149 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600150 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500151
152 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
153 png_error(png_ptr, "Out of Memory");
154
155 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600156 }
157 else
158 ret = farmalloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500159
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500160 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500161 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600162 png_error(png_ptr, "Out of Memory");
Guy Schalnat0d580581995-07-20 02:43:20 -0500163 }
164
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600165 return ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500166}
167
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600168/* free a pointer allocated by png_malloc(). In the default
169 configuration, png_ptr is not used, but is passed in case it
170 is needed. If ptr is NULL, return without taking any action. */
Guy Schalnat0d580581995-07-20 02:43:20 -0500171void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600172png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500173{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500174 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600175 return;
176
Andreas Dilger47a0c421997-05-16 02:46:07 -0500177 if (png_ptr->offset_table != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600178 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500179 int i;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600180
Andreas Dilger47a0c421997-05-16 02:46:07 -0500181 for (i = 0; i < png_ptr->offset_table_count; i++)
182 {
183 if (ptr == png_ptr->offset_table_ptr[i])
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600184 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500185 ptr = NULL;
186 png_ptr->offset_table_count_free++;
187 break;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600188 }
189 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500190 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
191 {
192 farfree(png_ptr->offset_table);
193 farfree(png_ptr->offset_table_ptr);
194 png_ptr->offset_table = NULL;
195 png_ptr->offset_table_ptr = NULL;
196 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600197 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500198
199 if (ptr != NULL)
200 farfree(ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600201}
202
203#else /* Not the Borland DOS special memory handler */
204
Guy Schalnate5a37791996-06-05 15:50:50 -0500205/* Allocate memory for a png_struct or a png_info. The malloc and
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600206 memset can be replaced by a single call to calloc() if this is thought
207 to improve performance noticably.*/
Guy Schalnate5a37791996-06-05 15:50:50 -0500208png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600209png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -0500210{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500211 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -0500212 png_voidp struct_ptr;
213
214 if (type == PNG_STRUCT_INFO)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500215 size = sizeof(png_info);
Guy Schalnate5a37791996-06-05 15:50:50 -0500216 else if (type == PNG_STRUCT_PNG)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500217 size = sizeof(png_struct);
Guy Schalnate5a37791996-06-05 15:50:50 -0500218 else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500219 return (png_voidp)NULL;
Guy Schalnate5a37791996-06-05 15:50:50 -0500220
221#if defined(__TURBOC__) && !defined(__FLAT__)
222 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
223#else
224# if defined(_MSC_VER) && defined(MAXSEG_64K)
Guy Schalnatc21f90c1996-06-17 16:24:45 -0500225 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500226# else
227 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
228# endif
229#endif
230 {
231 png_memset(struct_ptr, 0, size);
232 }
233
234 return (struct_ptr);
235}
236
237
238/* Free memory allocated by a png_create_struct() call */
239void
240png_destroy_struct(png_voidp struct_ptr)
241{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500242 if (struct_ptr != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500243#if defined(__TURBOC__) && !defined(__FLAT__)
244 farfree(struct_ptr);
245#else
246# if defined(_MSC_VER) && defined(MAXSEG_64K)
247 hfree(struct_ptr);
248# else
249 free(struct_ptr);
250# endif
251#endif
252}
253
254
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600255/* Allocate memory. For reasonable files, size should never exceed
256 64K. However, zlib may allocate more then 64K if you don't tell
Andreas Dilger47a0c421997-05-16 02:46:07 -0500257 it not to. See zconf.h and png.h for more information. zlib does
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600258 need to allocate exactly 64K, so whatever you call here must
259 have the ability to do that. */
260
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600261png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600262png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600263{
264 png_voidp ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500265 if (png_ptr == NULL || size == 0)
266 return (NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600267
268#ifdef PNG_MAX_MALLOC_64K
269 if (size > (png_uint_32)65536L)
270 png_error(png_ptr, "Cannot Allocate > 64K");
271#endif
272
273#if defined(__TURBOC__) && !defined(__FLAT__)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500274 ret = farmalloc((png_size_t)size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600275#else
276# if defined(_MSC_VER) && defined(MAXSEG_64K)
277 ret = halloc(size, 1);
278# else
279 ret = malloc(size);
280# endif
281#endif
282
283 if (ret == NULL)
284 {
285 png_error(png_ptr, "Out of Memory");
286 }
287
288 return ret;
289}
290
Andreas Dilger47a0c421997-05-16 02:46:07 -0500291/* Free a pointer allocated by png_malloc(). In the default
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600292 configuration, png_ptr is not used, but is passed in case it
293 is needed. If ptr is NULL, return without taking any action. */
294void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600295png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600296{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500297 if (png_ptr == NULL || ptr == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600298 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500299
Guy Schalnat6d764711995-12-19 03:22:19 -0600300#if defined(__TURBOC__) && !defined(__FLAT__)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500301 farfree(ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500302#else
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600303# if defined(_MSC_VER) && defined(MAXSEG_64K)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500304 hfree(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600305# else
Andreas Dilger47a0c421997-05-16 02:46:07 -0500306 free(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600307# endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500308#endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500309}
310
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600311#endif /* Not Borland DOS special memory handler */
Guy Schalnat6d764711995-12-19 03:22:19 -0600312