blob: c115e4c74fb206049435134614ba53228928ae0e [file] [log] [blame]
Guy Schalnat0d580581995-07-20 02:43:20 -05001
2/* pngstub.c - stub functions for i/o and memory allocation
3
Guy Schalnat51f0eb41995-09-26 05:22:39 -05004 libpng 1.0 beta 2 - version 0.81
Guy Schalnat0d580581995-07-20 02:43:20 -05005 For conditions of distribution and use, see copyright notice in png.h
6 Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
Guy Schalnat51f0eb41995-09-26 05:22:39 -05007 August 24, 1995
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
10 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 Schalnat0d580581995-07-20 02:43:20 -050016/* Allocate memory. For reasonable files, size should never exceed
17 64K. However, zlib may allocate more then 64K if you don't tell
18 it not to. See zconf.h and png.h for more information. zlib does
19 need to allocate exactly 64K, so whatever you call here must
20 have the ability to do that. */
21
22/* Borland compilers have this habit of not giving you 64K chunks
23 that start on the segment in DOS mode. This has not been observed
24 in Windows, and of course it doesn't matter in 32 bit mode, as there
25 are no segments. Now libpng doesn't need that much memory normally,
26 but zlib does, so we have to normalize it, if necessary. It would be
27 better if zlib worked in less then 64K, but it doesn't, so we
28 have to deal with it. Truely, we are misusing farmalloc here,
29 as it is designed for use with huge pointers, which don't care
30 about segments. So we allocate a large amount of memory, and
31 divvy off segments when needed.
32 */
33#ifdef __TURBOC__
34#ifndef __WIN32__
Guy Schalnat51f0eb41995-09-26 05:22:39 -050035#ifndef __FLAT__
Guy Schalnat0d580581995-07-20 02:43:20 -050036
37/* NUM_SEG is the number of segments allocated at once */
38#define NUM_SEG 4
39typedef struct borland_seg_struct
40{
41 void *mem_ptr;
42 void *seg_ptr[NUM_SEG];
43 int seg_used[NUM_SEG];
44 int num_used;
45} borland_seg;
46
47borland_seg *save_array;
48int num_save_array;
49int max_save_array;
50
51#endif
52#endif
Guy Schalnat51f0eb41995-09-26 05:22:39 -050053#endif
Guy Schalnat0d580581995-07-20 02:43:20 -050054
Guy Schalnat51f0eb41995-09-26 05:22:39 -050055voidpf
56png_large_malloc(png_structf *png_ptr, png_uint_32 size)
Guy Schalnat0d580581995-07-20 02:43:20 -050057{
Guy Schalnat51f0eb41995-09-26 05:22:39 -050058 voidpf ret;
59 if (!png_ptr || !size)
60 return ((void *)0);
Guy Schalnat0d580581995-07-20 02:43:20 -050061
62#ifdef PNG_MAX_MALLOC_64K
63 if (size > (png_uint_32)65536L)
64 png_error(png_ptr, "Cannot Allocate > 64K");
65#endif
66
67#ifdef __TURBOC__
Guy Schalnat51f0eb41995-09-26 05:22:39 -050068# if defined(__WIN32__) || defined(__FLAT__)
69 ret = malloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -050070# else
71
72 if (size == 65536L)
73 {
74 unsigned long offset;
75 if (!save_array)
76 {
77 ret = farmalloc(size);
78 offset = (unsigned long)(ret);
79 offset &= 0xffffL;
80 }
81 else
82 {
83 ret = (void *)0;
84 }
85 if (save_array || offset)
86 {
87 int i, j;
88
89 if (ret)
90 farfree(ret);
91 ret = (void *)0;
92
93 if (!save_array)
94 {
95 unsigned long offset;
96 png_byte huge *ptr;
97 int i;
98
99 num_save_array = 1;
100 save_array = malloc(num_save_array * sizeof (borland_seg));
101 if (!save_array)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500102 png_error(png_ptr, "Out of Memory 1");
Guy Schalnat0d580581995-07-20 02:43:20 -0500103 save_array->mem_ptr = farmalloc(
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500104 (unsigned long)(NUM_SEG) * 65536L + 65532L);
Guy Schalnat0d580581995-07-20 02:43:20 -0500105 if (!save_array->mem_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500106 png_error(png_ptr, "Out of Memory 2");
Guy Schalnat0d580581995-07-20 02:43:20 -0500107 offset = (unsigned long)(ret);
108 offset &= 0xffffL;
109 ptr = save_array->mem_ptr;
110 if (offset)
111 ptr += 65536L - offset;
112 for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
113 {
114 save_array->seg_ptr[i] = ptr;
115 save_array->seg_used[i] = 0;
116 }
117 save_array->num_used = 0;
118 }
119
120 for (i = 0; i < num_save_array; i++)
121 {
122 for (j = 0; j < NUM_SEG; j++)
123 {
124 if (!save_array[i].seg_used[j])
125 {
126 ret = save_array[i].seg_ptr[j];
127 save_array[i].seg_used[j] = 1;
128 save_array[i].num_used++;
129 break;
130 }
131 }
132 if (ret)
133 break;
134 }
135
136 if (!ret)
137 {
138 unsigned long offset;
139 png_byte huge *ptr;
140
141 save_array = realloc(save_array,
142 (num_save_array + 1) * sizeof (borland_seg));
143 if (!save_array)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500144 png_error(png_ptr, "Out of Memory 3");
Guy Schalnat0d580581995-07-20 02:43:20 -0500145 save_array[num_save_array].mem_ptr = farmalloc(
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500146 (unsigned long)(NUM_SEG) * 65536L + 65532L);
Guy Schalnat0d580581995-07-20 02:43:20 -0500147 if (!save_array[num_save_array].mem_ptr)
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500148 png_error(png_ptr, "Out of Memory 4");
Guy Schalnat0d580581995-07-20 02:43:20 -0500149 offset = (unsigned long)(ret);
150 offset &= 0xffffL;
151 ptr = save_array[num_save_array].mem_ptr;
152 if (offset)
153 ptr += 65536L - offset;
154 for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
155 {
156 save_array[num_save_array].seg_ptr[i] = ptr;
157 save_array[num_save_array].seg_used[i] = 0;
158 }
159 ret = save_array[num_save_array].seg_ptr[0];
160 save_array[num_save_array].seg_used[0] = 1;
161 save_array[num_save_array].num_used = 1;
162 num_save_array++;
163 }
164 }
165 }
166 else
167 {
168 ret = farmalloc(size);
169 }
170
171# endif /* __WIN32__ */
172#else /* __TURBOC__ */
173# ifdef _MSC_VER
174 ret = halloc(size, 1);
175# else
176 /* everybody else, so normal malloc should do it. */
177 ret = malloc(size);
178# endif
179#endif
180
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500181 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500182 {
183 png_error(png_ptr, "Out of Memory");
184 }
185
186 return ret;
187}
188
189/* free a pointer allocated by png_large_malloc(). In the default
190 configuration, png_ptr is not used, but is passed in case it
191 is needed. If ptr is NULL, return without taking any action. */
192void
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500193png_large_free(png_structf *png_ptr, voidpf ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500194{
195 if (!png_ptr)
196 return;
197
198 if (ptr != (void *)0)
199 {
200#ifdef __TURBOC__
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500201# if defined(__WIN32__) || defined(__FLAT__)
202 if (ptr)
203 free(ptr);
204# else
Guy Schalnat0d580581995-07-20 02:43:20 -0500205 int i, j;
206
207 for (i = 0; i < num_save_array; i++)
208 {
209 for (j = 0; j < NUM_SEG; j++)
210 {
211 if (ptr == save_array[i].seg_ptr[j])
212 {
Guy Schalnat0d580581995-07-20 02:43:20 -0500213 save_array[i].seg_used[j] = 0;
214 ptr = 0;
215 save_array[i].num_used--;
216 if (!save_array[i].num_used)
217 {
218 int k;
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500219
Guy Schalnat0d580581995-07-20 02:43:20 -0500220 num_save_array--;
221 farfree(save_array[i].mem_ptr);
222 for (k = i; k < num_save_array; k++)
223 save_array[k] = save_array[k + 1];
224 if (!num_save_array)
225 {
226 free(save_array);
227 save_array = 0;
228 }
229 }
230 break;
231 }
232 }
233 if (!ptr)
234 break;
235 }
236
Guy Schalnat0d580581995-07-20 02:43:20 -0500237 if (ptr)
238 farfree(ptr);
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500239# endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500240#else
241# ifdef _MSC_VER
242 hfree(ptr);
243# else
244 free(ptr);
245# endif
246#endif
247 }
248}
249
250/* Allocate memory. This is called for smallish blocks only It
251 should not get anywhere near 64K. */
252void *
253png_malloc(png_struct *png_ptr, png_uint_32 size)
254{
255 void *ret;
256
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500257 if (!png_ptr || !size)
Guy Schalnat0d580581995-07-20 02:43:20 -0500258 return ((void *)0);
259
260#ifdef PNG_MAX_MALLOC_64K
261 if (size > (png_uint_32)65536L)
262 png_error(png_ptr, "Cannot Allocate > 64K");
263#endif
264
265 ret = malloc((png_size_t)size);
266
267 if (!ret)
268 {
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500269 png_error(png_ptr, "Out of Memory 6");
Guy Schalnat0d580581995-07-20 02:43:20 -0500270 }
271
272 return ret;
273}
274
275/* Reallocate memory. This will not get near 64K on a
276 even marginally reasonable file. */
277void *
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500278png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size,
279 png_uint_32 old_size)
Guy Schalnat0d580581995-07-20 02:43:20 -0500280{
281 void *ret;
282
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500283 if (!png_ptr || !old_size || !ptr || !size)
Guy Schalnat0d580581995-07-20 02:43:20 -0500284 return ((void *)0);
285
286#ifdef PNG_MAX_MALLOC_64K
287 if (size > (png_uint_32)65536L)
288 png_error(png_ptr, "Cannot Allocate > 64K");
289#endif
290
291 ret = realloc(ptr, (png_size_t)size);
292
293 if (!ret)
294 {
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500295 png_error(png_ptr, "Out of Memory 7");
Guy Schalnat0d580581995-07-20 02:43:20 -0500296 }
297
298 return ret;
299}
300
301/* free a pointer allocated by png_malloc(). In the default
302 configuration, png_ptr is not used, but is passed incase it
303 is needed. If ptr is NULL, return without taking any action. */
304void
305png_free(png_struct *png_ptr, void *ptr)
306{
307 if (!png_ptr)
308 return;
309
310 if (ptr != (void *)0)
311 free(ptr);
312}
313