blob: 4c951170f5691486a63776318b25475f5fe268fa [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
Guy Schalnat0d580581995-07-20 02:43:20 -05003
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06004 libpng 1.0 beta 4 - version 0.90
Guy Schalnat0d580581995-07-20 02:43:20 -05005 For conditions of distribution and use, see copyright notice in png.h
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06006 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06007 January 10, 1997
Guy Schalnat0d580581995-07-20 02:43:20 -05008
Guy Schalnat51f0eb41995-09-26 05:22:39 -05009 This file provides a location for all memory allocation. Users which
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060010 need special memory handling are expected to modify the code in this file
11 to meet their needs. See the instructions at each function. */
Guy Schalnat0d580581995-07-20 02:43:20 -050012
13#define PNG_INTERNAL
14#include "png.h"
15
Guy Schalnat4ee97b01996-01-16 01:51:56 -060016/* Borland DOS special memory handler */
17#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
18/* if you change this, be sure to change the one in png.h also */
19
Guy Schalnate5a37791996-06-05 15:50:50 -050020/* Allocate memory for a png_struct. The malloc and memset can be replaced
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060021 by a single call to calloc() if this is thought to improve performance. */
Guy Schalnate5a37791996-06-05 15:50:50 -050022png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060023png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -050024{
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060025 png_size_t size;
Guy Schalnate5a37791996-06-05 15:50:50 -050026 png_voidp struct_ptr;
27
28 if (type == PNG_STRUCT_INFO)
29 size = sizeof(png_info);
30 else if (type == PNG_STRUCT_PNG)
31 size = sizeof(png_struct);
32 else
33 return (png_voidp)NULL;
34
35 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
36 {
37 png_memset(struct_ptr, 0, size);
38 }
39
40 return (struct_ptr);
41}
42
43
44/* Free memory allocated by a png_create_struct() call */
45void
46png_destroy_struct(png_voidp struct_ptr)
47{
48 if (struct_ptr)
49 farfree (struct_ptr);
50}
51
Guy Schalnat0d580581995-07-20 02:43:20 -050052/* Allocate memory. For reasonable files, size should never exceed
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060053 64K. However, zlib may allocate more then 64K if you don't tell
54 it not to. See zconf.h and png.h for more information. zlib does
55 need to allocate exactly 64K, so whatever you call here must
56 have the ability to do that. */
Guy Schalnat4ee97b01996-01-16 01:51:56 -060057
58/* Borland seems to have a problem in DOS mode for exactly 64K.
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060059 It gives you a segment with an offset of 8 (perhaps to store it's
60 memory stuff). zlib doesn't like this at all, so we have to
61 detect and deal with it. This code should not be needed in
Guy Schalnate5a37791996-06-05 15:50:50 -050062 Windows or OS/2 modes, and only in 16 bit mode. This code has
63 been updated by Alexander Lehmann for version 0.89 to waste less
64 memory.
Guy Schalnat4ee97b01996-01-16 01:51:56 -060065*/
66
67png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060068png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnat4ee97b01996-01-16 01:51:56 -060069{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060070 png_voidp ret;
71 if (!png_ptr || !size)
Guy Schalnate5a37791996-06-05 15:50:50 -050072 return ((voidp)NULL);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060073
74#ifdef PNG_MAX_MALLOC_64K
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060075 if (size > (png_uint_32)65536L)
76 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat4ee97b01996-01-16 01:51:56 -060077#endif
78
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060079 if (size == (png_uint_32)(65536L))
80 {
81 if (!png_ptr->offset_table)
82 {
83 /* try to see if we need to do any of this fancy stuff */
84 ret = farmalloc(size);
85 if (!ret || ((long)ret & 0xffff))
86 {
87 int num_blocks;
88 png_uint_32 total_size;
89 png_bytep table;
90 int i;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060091 png_byte huge * hptr;
92
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060093 if (ret)
94 farfree(ret);
Guy Schalnate5a37791996-06-05 15:50:50 -050095 ret = NULL;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060096
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060097 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
98 if (num_blocks < 1)
99 num_blocks = 1;
100 if (png_ptr->zlib_mem_level >= 7)
101 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
102 else
103 num_blocks++;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600104
Guy Schalnate5a37791996-06-05 15:50:50 -0500105 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600106
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600107 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600108
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600109 if (!table)
110 {
111 png_error(png_ptr, "Out of Memory");
112 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600113
Guy Schalnate5a37791996-06-05 15:50:50 -0500114 if ((long)table & 0xfff0)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600115 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500116 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600117 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600118
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600119 png_ptr->offset_table = table;
120 png_ptr->offset_table_ptr = farmalloc(
121 num_blocks * sizeof (png_bytep));
Guy Schalnate5a37791996-06-05 15:50:50 -0500122
123 if (!png_ptr->offset_table_ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600124 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500125 png_error(png_ptr, "Out of memory");
126 }
127
128 hptr = (png_byte huge *)table;
129 if ((long)hptr & 0xf)
130 {
131 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
132 hptr += 16L;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600133 }
134 for (i = 0; i < num_blocks; i++)
135 {
136 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
137 hptr += 65536L;
138 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600139
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600140 png_ptr->offset_table_number = num_blocks;
141 png_ptr->offset_table_count = 0;
142 png_ptr->offset_table_count_free = 0;
143 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600144 }
Guy Schalnate5a37791996-06-05 15:50:50 -0500145
146 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
147 png_error(png_ptr, "Out of Memory");
148
149 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600150 }
151 else
152 ret = farmalloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500153
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500154 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500155 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600156 png_error(png_ptr, "Out of Memory");
Guy Schalnat0d580581995-07-20 02:43:20 -0500157 }
158
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600159 return ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500160}
161
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600162/* free a pointer allocated by png_malloc(). In the default
163 configuration, png_ptr is not used, but is passed in case it
164 is needed. If ptr is NULL, return without taking any action. */
Guy Schalnat0d580581995-07-20 02:43:20 -0500165void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600166png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500167{
168 if (!png_ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600169 return;
170
171 if (ptr != NULL)
172 {
173 if (png_ptr->offset_table)
174 {
175 int i;
176
177 for (i = 0; i < png_ptr->offset_table_count; i++)
178 {
179 if (ptr == png_ptr->offset_table_ptr[i])
180 {
181 ptr = 0;
182 png_ptr->offset_table_count_free++;
183 break;
184 }
185 }
186 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
187 {
188 farfree(png_ptr->offset_table);
189 farfree(png_ptr->offset_table_ptr);
190 png_ptr->offset_table = 0;
191 png_ptr->offset_table_ptr = 0;
192 }
193 }
194
195 if (ptr)
196 farfree(ptr);
197 }
198}
199
200#else /* Not the Borland DOS special memory handler */
201
Guy Schalnate5a37791996-06-05 15:50:50 -0500202/* Allocate memory for a png_struct or a png_info. The malloc and
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600203 memset can be replaced by a single call to calloc() if this is thought
204 to improve performance noticably.*/
Guy Schalnate5a37791996-06-05 15:50:50 -0500205png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600206png_create_struct(int type)
Guy Schalnate5a37791996-06-05 15:50:50 -0500207{
208 size_t size;
209 png_voidp struct_ptr;
210
211 if (type == PNG_STRUCT_INFO)
212 size = sizeof(png_info);
213 else if (type == PNG_STRUCT_PNG)
214 size = sizeof(png_struct);
215 else
216 return (png_voidp)NULL;
217
218#if defined(__TURBOC__) && !defined(__FLAT__)
219 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
220#else
221# if defined(_MSC_VER) && defined(MAXSEG_64K)
Guy Schalnatc21f90c1996-06-17 16:24:45 -0500222 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500223# else
224 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
225# endif
226#endif
227 {
228 png_memset(struct_ptr, 0, size);
229 }
230
231 return (struct_ptr);
232}
233
234
235/* Free memory allocated by a png_create_struct() call */
236void
237png_destroy_struct(png_voidp struct_ptr)
238{
239 if (struct_ptr)
240#if defined(__TURBOC__) && !defined(__FLAT__)
241 farfree(struct_ptr);
242#else
243# if defined(_MSC_VER) && defined(MAXSEG_64K)
244 hfree(struct_ptr);
245# else
246 free(struct_ptr);
247# endif
248#endif
249}
250
251
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600252/* Allocate memory. For reasonable files, size should never exceed
253 64K. However, zlib may allocate more then 64K if you don't tell
254 it not to. See zconf.h and png.h for more information. zlib does
255 need to allocate exactly 64K, so whatever you call here must
256 have the ability to do that. */
257
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600258#ifndef FORTIFY
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600259png_voidp
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600260png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600261{
262 png_voidp ret;
263 if (!png_ptr || !size)
264 return ((voidp)0);
265
266#ifdef PNG_MAX_MALLOC_64K
267 if (size > (png_uint_32)65536L)
268 png_error(png_ptr, "Cannot Allocate > 64K");
269#endif
270
271#if defined(__TURBOC__) && !defined(__FLAT__)
272 ret = farmalloc(size);
273#else
274# if defined(_MSC_VER) && defined(MAXSEG_64K)
275 ret = halloc(size, 1);
276# else
277 ret = malloc(size);
278# endif
279#endif
280
281 if (ret == NULL)
282 {
283 png_error(png_ptr, "Out of Memory");
284 }
285
286 return ret;
287}
288
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600289/* free a pointer allocated by png_malloc(). In the default
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600290 configuration, png_ptr is not used, but is passed in case it
291 is needed. If ptr is NULL, return without taking any action. */
292void
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600293png_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600294{
295 if (!png_ptr)
296 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500297
Guy Schalnat6d764711995-12-19 03:22:19 -0600298 if (ptr != NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500299 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600300#if defined(__TURBOC__) && !defined(__FLAT__)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600301 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)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600304 hfree(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600305# else
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600306 free(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600307# endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500308#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600309 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500310}
311
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600312#endif /* FORTIFY */
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600313#endif /* Not Borland DOS special memory handler */
Guy Schalnat6d764711995-12-19 03:22:19 -0600314