]> git.saurik.com Git - wxWidgets.git/blame - src/png/pngmem.c
Added wxUSE_DC_CACHEING and associated code to wxMSW
[wxWidgets.git] / src / png / pngmem.c
CommitLineData
c801d85f
KB
1
2/* pngmem.c - stub functions for memory allocation
3 *
a626cc03 4 * libpng 1.0.3 - January 14, 1999
c801d85f
KB
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
a626cc03 8 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
c801d85f 9 *
a626cc03
RR
10 * This file provides a location for all memory allocation. Users who
11 * need special memory handling are expected to supply replacement
12 * functions for png_malloc() and png_free(), and to use
13 * png_create_read_struct_2() and png_create_write_struct_2() to
14 * identify the replacement functions.
c801d85f
KB
15 */
16
17#define PNG_INTERNAL
a626cc03 18#include "png.h"
c801d85f
KB
19
20/* Borland DOS special memory handler */
21#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
22/* if you change this, be sure to change the one in png.h also */
23
24/* Allocate memory for a png_struct. The malloc and memset can be replaced
25 by a single call to calloc() if this is thought to improve performance. */
26png_voidp
27png_create_struct(int type)
28{
a626cc03
RR
29#ifdef PNG_USER_MEM_SUPPORTED
30 return (png_create_struct_2(type, NULL));
31}
32
33/* Alternate version of png_create_struct, for use with user-defined malloc. */
34png_voidp
35png_create_struct_2(int type, png_malloc_ptr malloc_fn)
36{
37#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
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
a626cc03
RR
48#ifdef PNG_USER_MEM_SUPPORTED
49 if(malloc_fn != NULL)
50 {
51 if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
52 png_memset(struct_ptr, 0, size);
53 return (struct_ptr);
54 }
55#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
56 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
57 {
58 png_memset(struct_ptr, 0, size);
59 }
c801d85f
KB
60 return (struct_ptr);
61}
62
63
64/* Free memory allocated by a png_create_struct() call */
65void
66png_destroy_struct(png_voidp struct_ptr)
67{
a626cc03
RR
68#ifdef PNG_USER_MEM_SUPPORTED
69 png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
70}
71
72/* Free memory allocated by a png_create_struct() call */
73void
74png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
75{
76#endif
c801d85f
KB
77 if (struct_ptr != NULL)
78 {
a626cc03
RR
79#ifdef PNG_USER_MEM_SUPPORTED
80 if(free_fn != NULL)
81 {
82 png_struct dummy_struct;
83 png_structp png_ptr = &dummy_struct;
84 (*(free_fn))(png_ptr, struct_ptr);
85 struct_ptr = NULL;
86 return;
87 }
88#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
89 farfree (struct_ptr);
90 struct_ptr = NULL;
91 }
92}
93
94/* Allocate memory. For reasonable files, size should never exceed
95 * 64K. However, zlib may allocate more then 64K if you don't tell
96 * it not to. See zconf.h and png.h for more information. zlib does
97 * need to allocate exactly 64K, so whatever you call here must
98 * have the ability to do that.
99 *
100 * Borland seems to have a problem in DOS mode for exactly 64K.
a626cc03 101 * It gives you a segment with an offset of 8 (perhaps to store its
c801d85f
KB
102 * memory stuff). zlib doesn't like this at all, so we have to
103 * detect and deal with it. This code should not be needed in
104 * Windows or OS/2 modes, and only in 16 bit mode. This code has
105 * been updated by Alexander Lehmann for version 0.89 to waste less
106 * memory.
107 *
108 * Note that we can't use png_size_t for the "size" declaration,
109 * since on some systems a png_size_t is a 16-bit quantity, and as a
110 * result, we would be truncating potentially larger memory requests
111 * (which should cause a fatal error) and introducing major problems.
112 */
113png_voidp
a626cc03 114png_malloc(png_structp png_ptr, png_uint_32 size)
c801d85f 115{
a626cc03 116#ifndef PNG_USER_MEM_SUPPORTED
c801d85f 117 png_voidp ret;
a626cc03 118#endif
c801d85f
KB
119 if (png_ptr == NULL || size == 0)
120 return ((png_voidp)NULL);
121
a626cc03
RR
122#ifdef PNG_USER_MEM_SUPPORTED
123 if(png_ptr->malloc_fn != NULL)
124 return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
125 else
126 return png_malloc_default(png_ptr, size);
127}
128
129png_voidp
130png_malloc_default(png_structp png_ptr, png_uint_32 size)
131{
132 png_voidp ret;
133#endif /* PNG_USER_MEM_SUPPORTED */
134
c801d85f
KB
135#ifdef PNG_MAX_MALLOC_64K
136 if (size > (png_uint_32)65536L)
137 png_error(png_ptr, "Cannot Allocate > 64K");
138#endif
139
140 if (size == (png_uint_32)65536L)
141 {
142 if (png_ptr->offset_table == NULL)
143 {
144 /* try to see if we need to do any of this fancy stuff */
145 ret = farmalloc(size);
146 if (ret == NULL || ((png_size_t)ret & 0xffff))
147 {
148 int num_blocks;
149 png_uint_32 total_size;
150 png_bytep table;
151 int i;
152 png_byte huge * hptr;
153
154 if (ret != NULL)
155 {
156 farfree(ret);
157 ret = NULL;
158 }
159
160 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
161 if (num_blocks < 1)
162 num_blocks = 1;
163 if (png_ptr->zlib_mem_level >= 7)
164 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
165 else
166 num_blocks++;
167
168 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
169
170 table = farmalloc(total_size);
171
172 if (table == NULL)
173 {
174 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
175 }
176
177 if ((png_size_t)table & 0xfff0)
178 {
179 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
180 }
181
182 png_ptr->offset_table = table;
183 png_ptr->offset_table_ptr = farmalloc(num_blocks *
184 sizeof (png_bytep));
185
186 if (png_ptr->offset_table_ptr == NULL)
187 {
188 png_error(png_ptr, "Out Of memory.");
189 }
190
191 hptr = (png_byte huge *)table;
192 if ((png_size_t)hptr & 0xf)
193 {
194 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
195 hptr += 16L;
196 }
197 for (i = 0; i < num_blocks; i++)
198 {
199 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
200 hptr += (png_uint_32)65536L;
201 }
202
203 png_ptr->offset_table_number = num_blocks;
204 png_ptr->offset_table_count = 0;
205 png_ptr->offset_table_count_free = 0;
206 }
207 }
208
209 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
210 png_error(png_ptr, "Out of Memory.");
211
212 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
213 }
214 else
215 ret = farmalloc(size);
216
217 if (ret == NULL)
218 {
219 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
220 }
221
222 return (ret);
223}
224
a626cc03 225/* free a pointer allocated by png_malloc(). In the default
c801d85f
KB
226 configuration, png_ptr is not used, but is passed in case it
227 is needed. If ptr is NULL, return without taking any action. */
228void
a626cc03 229png_free(png_structp png_ptr, png_voidp ptr)
c801d85f
KB
230{
231 if (png_ptr == NULL || ptr == NULL)
232 return;
233
a626cc03
RR
234#ifdef PNG_USER_MEM_SUPPORTED
235 if (png_ptr->free_fn != NULL)
236 {
237 (*(png_ptr->free_fn))(png_ptr, ptr);
238 ptr = NULL;
239 return;
240 }
241 else png_free_default(png_ptr, ptr);
242}
243
244void
245png_free_default(png_structp png_ptr, png_voidp ptr)
246{
247#endif /* PNG_USER_MEM_SUPPORTED */
248
c801d85f
KB
249 if (png_ptr->offset_table != NULL)
250 {
251 int i;
252
253 for (i = 0; i < png_ptr->offset_table_count; i++)
254 {
255 if (ptr == png_ptr->offset_table_ptr[i])
256 {
257 ptr = NULL;
258 png_ptr->offset_table_count_free++;
259 break;
260 }
261 }
262 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
263 {
264 farfree(png_ptr->offset_table);
265 farfree(png_ptr->offset_table_ptr);
266 png_ptr->offset_table = NULL;
267 png_ptr->offset_table_ptr = NULL;
268 }
269 }
270
271 if (ptr != NULL)
272 {
273 farfree(ptr);
274 ptr = NULL;
275 }
276}
277
278#else /* Not the Borland DOS special memory handler */
279
280/* Allocate memory for a png_struct or a png_info. The malloc and
281 memset can be replaced by a single call to calloc() if this is thought
282 to improve performance noticably.*/
283png_voidp
284png_create_struct(int type)
285{
a626cc03
RR
286#ifdef PNG_USER_MEM_SUPPORTED
287 return (png_create_struct_2(type, NULL));
288}
289
290/* Allocate memory for a png_struct or a png_info. The malloc and
291 memset can be replaced by a single call to calloc() if this is thought
292 to improve performance noticably.*/
293png_voidp
294png_create_struct_2(int type, png_malloc_ptr malloc_fn)
295{
296#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
297 png_size_t size;
298 png_voidp struct_ptr;
299
300 if (type == PNG_STRUCT_INFO)
301 size = sizeof(png_info);
302 else if (type == PNG_STRUCT_PNG)
303 size = sizeof(png_struct);
304 else
305 return ((png_voidp)NULL);
306
a626cc03
RR
307#ifdef PNG_USER_MEM_SUPPORTED
308 if(malloc_fn != NULL)
309 {
310 if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
311 png_memset(struct_ptr, 0, size);
312 return (struct_ptr);
313 }
314#endif /* PNG_USER_MEM_SUPPORTED */
315
c801d85f
KB
316#if defined(__TURBOC__) && !defined(__FLAT__)
317 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
318#else
319# if defined(_MSC_VER) && defined(MAXSEG_64K)
320 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
321# else
322 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
323# endif
324#endif
325 {
326 png_memset(struct_ptr, 0, size);
327 }
328
329 return (struct_ptr);
330}
331
332
333/* Free memory allocated by a png_create_struct() call */
334void
335png_destroy_struct(png_voidp struct_ptr)
336{
a626cc03
RR
337#ifdef PNG_USER_MEM_SUPPORTED
338 png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
339}
340
341/* Free memory allocated by a png_create_struct() call */
342void
343png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
344{
345#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
346 if (struct_ptr != NULL)
347 {
a626cc03
RR
348#ifdef PNG_USER_MEM_SUPPORTED
349 if(free_fn != NULL)
350 {
351 png_struct dummy_struct;
352 png_structp png_ptr = &dummy_struct;
353 (*(free_fn))(png_ptr, struct_ptr);
354 struct_ptr = NULL;
355 return;
356 }
357#endif /* PNG_USER_MEM_SUPPORTED */
c801d85f
KB
358#if defined(__TURBOC__) && !defined(__FLAT__)
359 farfree(struct_ptr);
a626cc03 360 struct_ptr = NULL;
c801d85f
KB
361#else
362# if defined(_MSC_VER) && defined(MAXSEG_64K)
363 hfree(struct_ptr);
a626cc03 364 struct_ptr = NULL;
c801d85f
KB
365# else
366 free(struct_ptr);
a626cc03 367 struct_ptr = NULL;
c801d85f
KB
368# endif
369#endif
370 }
371}
372
373
374/* Allocate memory. For reasonable files, size should never exceed
375 64K. However, zlib may allocate more then 64K if you don't tell
376 it not to. See zconf.h and png.h for more information. zlib does
377 need to allocate exactly 64K, so whatever you call here must
378 have the ability to do that. */
379
380png_voidp
a626cc03 381png_malloc(png_structp png_ptr, png_uint_32 size)
c801d85f 382{
a626cc03 383#ifndef PNG_USER_MEM_SUPPORTED
c801d85f 384 png_voidp ret;
a626cc03 385#endif
c801d85f
KB
386 if (png_ptr == NULL || size == 0)
387 return ((png_voidp)NULL);
388
a626cc03
RR
389#ifdef PNG_USER_MEM_SUPPORTED
390 if(png_ptr->malloc_fn != NULL)
391 return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
392 else
393 return (png_malloc_default(png_ptr, size));
394}
395png_voidp
396png_malloc_default(png_structp png_ptr, png_uint_32 size)
397{
398 png_voidp ret;
399#endif /* PNG_USER_MEM_SUPPORTED */
400
c801d85f
KB
401#ifdef PNG_MAX_MALLOC_64K
402 if (size > (png_uint_32)65536L)
403 png_error(png_ptr, "Cannot Allocate > 64K");
404#endif
405
406#if defined(__TURBOC__) && !defined(__FLAT__)
407 ret = farmalloc(size);
408#else
409# if defined(_MSC_VER) && defined(MAXSEG_64K)
410 ret = halloc(size, 1);
411# else
412 ret = malloc((size_t)size);
413# endif
414#endif
415
416 if (ret == NULL)
417 {
418 png_error(png_ptr, "Out of Memory");
419 }
420
421 return (ret);
422}
423
a626cc03
RR
424/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
425 without taking any action. */
c801d85f 426void
a626cc03 427png_free(png_structp png_ptr, png_voidp ptr)
c801d85f
KB
428{
429 if (png_ptr == NULL || ptr == NULL)
430 return;
431
a626cc03
RR
432#ifdef PNG_USER_MEM_SUPPORTED
433 if (png_ptr->free_fn != NULL)
434 {
435 (*(png_ptr->free_fn))(png_ptr, ptr);
436 ptr = NULL;
437 return;
438 }
439 else png_free_default(png_ptr, ptr);
440}
441void
442png_free_default(png_structp png_ptr, png_voidp ptr)
443{
444#endif /* PNG_USER_MEM_SUPPORTED */
445
c801d85f
KB
446#if defined(__TURBOC__) && !defined(__FLAT__)
447 farfree(ptr);
a626cc03 448 ptr = NULL;
c801d85f
KB
449#else
450# if defined(_MSC_VER) && defined(MAXSEG_64K)
451 hfree(ptr);
a626cc03 452 ptr = NULL;
c801d85f
KB
453# else
454 free(ptr);
a626cc03 455 ptr = NULL;
c801d85f
KB
456# endif
457#endif
458}
459
460#endif /* Not Borland DOS special memory handler */
461
462png_voidp
463png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
464 png_uint_32 length)
465{
466 png_size_t size;
467
468 size = (png_size_t)length;
469 if ((png_uint_32)size != length)
470 png_error(png_ptr,"Overflow in png_memcpy_check.");
a626cc03 471
c801d85f
KB
472 return(png_memcpy (s1, s2, size));
473}
474
475png_voidp
476png_memset_check (png_structp png_ptr, png_voidp s1, int value,
477 png_uint_32 length)
478{
479 png_size_t size;
480
481 size = (png_size_t)length;
482 if ((png_uint_32)size != length)
483 png_error(png_ptr,"Overflow in png_memset_check.");
484
485 return (png_memset (s1, value, size));
486
487}
a626cc03
RR
488
489#ifdef PNG_USER_MEM_SUPPORTED
490/* This function is called when the application wants to use another method
491 * of allocating and freeing memory.
492 */
493void
494png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
495 malloc_fn, png_free_ptr free_fn)
496{
497 png_ptr->mem_ptr = mem_ptr;
498 png_ptr->malloc_fn = malloc_fn;
499 png_ptr->free_fn = free_fn;
500}
501
502/* This function returns a pointer to the mem_ptr associated with the user
503 * functions. The application should free any memory associated with this
504 * pointer before png_write_destroy and png_read_destroy are called.
505 */
506png_voidp
507png_get_mem_ptr(png_structp png_ptr)
508{
509 return ((png_voidp)png_ptr->mem_ptr);
510}
511#endif /* PNG_USER_MEM_SUPPORTED */