]> git.saurik.com Git - wxWidgets.git/blob - src/png/pngmem.c
Seems it works reasonably stable...
[wxWidgets.git] / src / png / pngmem.c
1
2 /* pngmem.c - stub functions for memory allocation
3 *
4 * libpng 1.0.1
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 * Copyright (c) 1998, Glenn Randers-Pehrson
9 * March 15, 1998
10 *
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 */
15
16 #define PNG_INTERNAL
17 #include "../png/png.h"
18
19 /* The following "hides" PNG_MALLOC and PNG_FREE thus allowing the pngtest
20 application to put a wrapper on top of them. */
21 #ifdef PNGTEST_MEMORY_DEBUG
22 #define PNG_MALLOC png_debug_malloc
23 #define PNG_FREE png_debug_free
24 #else
25 #define PNG_MALLOC png_malloc
26 #define PNG_FREE png_free
27 #endif
28
29 /* Borland DOS special memory handler */
30 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
31 /* if you change this, be sure to change the one in png.h also */
32
33 /* Allocate memory for a png_struct. The malloc and memset can be replaced
34 by a single call to calloc() if this is thought to improve performance. */
35 png_voidp
36 png_create_struct(int type)
37 {
38 png_size_t size;
39 png_voidp struct_ptr;
40
41 if (type == PNG_STRUCT_INFO)
42 size = sizeof(png_info);
43 else if (type == PNG_STRUCT_PNG)
44 size = sizeof(png_struct);
45 else
46 return ((png_voidp)NULL);
47
48 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
49 {
50 png_memset(struct_ptr, 0, size);
51 }
52
53 return (struct_ptr);
54 }
55
56
57 /* Free memory allocated by a png_create_struct() call */
58 void
59 png_destroy_struct(png_voidp struct_ptr)
60 {
61 if (struct_ptr != NULL)
62 {
63 farfree (struct_ptr);
64 struct_ptr = NULL;
65 }
66 }
67
68 /* Allocate memory. For reasonable files, size should never exceed
69 * 64K. However, zlib may allocate more then 64K if you don't tell
70 * it not to. See zconf.h and png.h for more information. zlib does
71 * need to allocate exactly 64K, so whatever you call here must
72 * have the ability to do that.
73 *
74 * Borland seems to have a problem in DOS mode for exactly 64K.
75 * It gives you a segment with an offset of 8 (perhaps to store it's
76 * memory stuff). zlib doesn't like this at all, so we have to
77 * detect and deal with it. This code should not be needed in
78 * Windows or OS/2 modes, and only in 16 bit mode. This code has
79 * been updated by Alexander Lehmann for version 0.89 to waste less
80 * memory.
81 *
82 * Note that we can't use png_size_t for the "size" declaration,
83 * since on some systems a png_size_t is a 16-bit quantity, and as a
84 * result, we would be truncating potentially larger memory requests
85 * (which should cause a fatal error) and introducing major problems.
86 */
87 png_voidp
88 PNG_MALLOC(png_structp png_ptr, png_uint_32 size)
89 {
90 png_voidp ret;
91 if (png_ptr == NULL || size == 0)
92 return ((png_voidp)NULL);
93
94 #ifdef PNG_MAX_MALLOC_64K
95 if (size > (png_uint_32)65536L)
96 png_error(png_ptr, "Cannot Allocate > 64K");
97 #endif
98
99 if (size == (png_uint_32)65536L)
100 {
101 if (png_ptr->offset_table == NULL)
102 {
103 /* try to see if we need to do any of this fancy stuff */
104 ret = farmalloc(size);
105 if (ret == NULL || ((png_size_t)ret & 0xffff))
106 {
107 int num_blocks;
108 png_uint_32 total_size;
109 png_bytep table;
110 int i;
111 png_byte huge * hptr;
112
113 if (ret != NULL)
114 {
115 farfree(ret);
116 ret = NULL;
117 }
118
119 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
120 if (num_blocks < 1)
121 num_blocks = 1;
122 if (png_ptr->zlib_mem_level >= 7)
123 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
124 else
125 num_blocks++;
126
127 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
128
129 table = farmalloc(total_size);
130
131 if (table == NULL)
132 {
133 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
134 }
135
136 if ((png_size_t)table & 0xfff0)
137 {
138 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
139 }
140
141 png_ptr->offset_table = table;
142 png_ptr->offset_table_ptr = farmalloc(num_blocks *
143 sizeof (png_bytep));
144
145 if (png_ptr->offset_table_ptr == NULL)
146 {
147 png_error(png_ptr, "Out Of memory.");
148 }
149
150 hptr = (png_byte huge *)table;
151 if ((png_size_t)hptr & 0xf)
152 {
153 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
154 hptr += 16L;
155 }
156 for (i = 0; i < num_blocks; i++)
157 {
158 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
159 hptr += (png_uint_32)65536L;
160 }
161
162 png_ptr->offset_table_number = num_blocks;
163 png_ptr->offset_table_count = 0;
164 png_ptr->offset_table_count_free = 0;
165 }
166 }
167
168 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
169 png_error(png_ptr, "Out of Memory.");
170
171 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
172 }
173 else
174 ret = farmalloc(size);
175
176 if (ret == NULL)
177 {
178 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
179 }
180
181 return (ret);
182 }
183
184 /* free a pointer allocated by PNG_MALLOC(). In the default
185 configuration, png_ptr is not used, but is passed in case it
186 is needed. If ptr is NULL, return without taking any action. */
187 void
188 PNG_FREE(png_structp png_ptr, png_voidp ptr)
189 {
190 if (png_ptr == NULL || ptr == NULL)
191 return;
192
193 if (png_ptr->offset_table != NULL)
194 {
195 int i;
196
197 for (i = 0; i < png_ptr->offset_table_count; i++)
198 {
199 if (ptr == png_ptr->offset_table_ptr[i])
200 {
201 ptr = NULL;
202 png_ptr->offset_table_count_free++;
203 break;
204 }
205 }
206 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
207 {
208 farfree(png_ptr->offset_table);
209 farfree(png_ptr->offset_table_ptr);
210 png_ptr->offset_table = NULL;
211 png_ptr->offset_table_ptr = NULL;
212 }
213 }
214
215 if (ptr != NULL)
216 {
217 farfree(ptr);
218 ptr = NULL;
219 }
220 }
221
222 #else /* Not the Borland DOS special memory handler */
223
224 /* Allocate memory for a png_struct or a png_info. The malloc and
225 memset can be replaced by a single call to calloc() if this is thought
226 to improve performance noticably.*/
227 png_voidp
228 png_create_struct(int type)
229 {
230 png_size_t size;
231 png_voidp struct_ptr;
232
233 if (type == PNG_STRUCT_INFO)
234 size = sizeof(png_info);
235 else if (type == PNG_STRUCT_PNG)
236 size = sizeof(png_struct);
237 else
238 return ((png_voidp)NULL);
239
240 #if defined(__TURBOC__) && !defined(__FLAT__)
241 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
242 #else
243 # if defined(_MSC_VER) && defined(MAXSEG_64K)
244 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
245 # else
246 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
247 # endif
248 #endif
249 {
250 png_memset(struct_ptr, 0, size);
251 }
252
253 return (struct_ptr);
254 }
255
256
257 /* Free memory allocated by a png_create_struct() call */
258 void
259 png_destroy_struct(png_voidp struct_ptr)
260 {
261 if (struct_ptr != NULL)
262 {
263 #if defined(__TURBOC__) && !defined(__FLAT__)
264 farfree(struct_ptr);
265 #else
266 # if defined(_MSC_VER) && defined(MAXSEG_64K)
267 hfree(struct_ptr);
268 # else
269 free(struct_ptr);
270 # endif
271 #endif
272 }
273 }
274
275
276 /* Allocate memory. For reasonable files, size should never exceed
277 64K. However, zlib may allocate more then 64K if you don't tell
278 it not to. See zconf.h and png.h for more information. zlib does
279 need to allocate exactly 64K, so whatever you call here must
280 have the ability to do that. */
281
282 png_voidp
283 PNG_MALLOC(png_structp png_ptr, png_uint_32 size)
284 {
285 png_voidp ret;
286
287 if (png_ptr == NULL || size == 0)
288 return ((png_voidp)NULL);
289
290 #ifdef PNG_MAX_MALLOC_64K
291 if (size > (png_uint_32)65536L)
292 png_error(png_ptr, "Cannot Allocate > 64K");
293 #endif
294
295 #if defined(__TURBOC__) && !defined(__FLAT__)
296 ret = farmalloc(size);
297 #else
298 # if defined(_MSC_VER) && defined(MAXSEG_64K)
299 ret = halloc(size, 1);
300 # else
301 ret = malloc((size_t)size);
302 # endif
303 #endif
304
305 if (ret == NULL)
306 {
307 png_error(png_ptr, "Out of Memory");
308 }
309
310 return (ret);
311 }
312
313 /* Free a pointer allocated by PNG_MALLOC(). In the default
314 configuration, png_ptr is not used, but is passed in case it
315 is needed. If ptr is NULL, return without taking any action. */
316 void
317 PNG_FREE(png_structp png_ptr, png_voidp ptr)
318 {
319 if (png_ptr == NULL || ptr == NULL)
320 return;
321
322 #if defined(__TURBOC__) && !defined(__FLAT__)
323 farfree(ptr);
324 #else
325 # if defined(_MSC_VER) && defined(MAXSEG_64K)
326 hfree(ptr);
327 # else
328 free(ptr);
329 # endif
330 #endif
331 }
332
333 #endif /* Not Borland DOS special memory handler */
334
335 png_voidp
336 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
337 png_uint_32 length)
338 {
339 png_size_t size;
340
341 size = (png_size_t)length;
342 if ((png_uint_32)size != length)
343 png_error(png_ptr,"Overflow in png_memcpy_check.");
344
345 return(png_memcpy (s1, s2, size));
346 }
347
348 png_voidp
349 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
350 png_uint_32 length)
351 {
352 png_size_t size;
353
354 size = (png_size_t)length;
355 if ((png_uint_32)size != length)
356 png_error(png_ptr,"Overflow in png_memset_check.");
357
358 return (png_memset (s1, value, size));
359
360 }