blob: 63200fd6a7799deba9d1c42d504d8939d070aa9e [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
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06004 libpng 1.0 beta 2 - version 0.88
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.
7 January 25, 1996
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 Schalnat0d580581995-07-20 02:43:20 -050020/* Allocate memory. For reasonable files, size should never exceed
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060021 64K. However, zlib may allocate more then 64K if you don't tell
22 it not to. See zconf.h and png.h for more information. zlib does
23 need to allocate exactly 64K, so whatever you call here must
24 have the ability to do that. */
Guy Schalnat4ee97b01996-01-16 01:51:56 -060025
26/* Borland seems to have a problem in DOS mode for exactly 64K.
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060027 It gives you a segment with an offset of 8 (perhaps to store it's
28 memory stuff). zlib doesn't like this at all, so we have to
29 detect and deal with it. This code should not be needed in
Guy Schalnat4ee97b01996-01-16 01:51:56 -060030 Windows or OS/2 modes, and only in 16 bit mode.
31*/
32
33png_voidp
34png_large_malloc(png_structp png_ptr, png_uint_32 size)
35{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060036 png_voidp ret;
37 if (!png_ptr || !size)
38 return ((voidp)0);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060039
40#ifdef PNG_MAX_MALLOC_64K
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060041 if (size > (png_uint_32)65536L)
42 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat4ee97b01996-01-16 01:51:56 -060043#endif
44
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060045 if (size == (png_uint_32)(65536L))
46 {
47 if (!png_ptr->offset_table)
48 {
49 /* try to see if we need to do any of this fancy stuff */
50 ret = farmalloc(size);
51 if (!ret || ((long)ret & 0xffff))
52 {
53 int num_blocks;
54 png_uint_32 total_size;
55 png_bytep table;
56 int i;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060057 png_byte huge * hptr;
58
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060059 if (ret)
60 farfree(ret);
61 ret = 0;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060062
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060063 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
64 if (num_blocks < 1)
65 num_blocks = 1;
66 if (png_ptr->zlib_mem_level >= 7)
67 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
68 else
69 num_blocks++;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060070
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060071 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks;
Guy Schalnat4ee97b01996-01-16 01:51:56 -060072
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060073 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060074
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060075 if (!table)
76 {
77 png_error(png_ptr, "Out of Memory");
78 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -060079
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060080 if ((long)table & 0xffff)
81 {
82 farfree(table);
83 total_size += (png_uint_32)65536L;
84 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -060085
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060086 table = farmalloc(total_size);
Guy Schalnat4ee97b01996-01-16 01:51:56 -060087
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060088 if (!table)
89 {
90 png_error(png_ptr, "Out of Memory");
91 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -060092
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060093 png_ptr->offset_table = table;
94 png_ptr->offset_table_ptr = farmalloc(
95 num_blocks * sizeof (png_bytep));
96 hptr = (png_byte huge *)table;
97 if ((long)hptr & 0xffff)
98 {
99 hptr = (png_byte huge *)((long)(hptr) & 0xffff0000L);
100 hptr += 65536L;
101 }
102 for (i = 0; i < num_blocks; i++)
103 {
104 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
105 hptr += 65536L;
106 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600107
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600108 png_ptr->offset_table_number = num_blocks;
109 png_ptr->offset_table_count = 0;
110 png_ptr->offset_table_count_free = 0;
111 }
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600112
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600113 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
114 png_error(png_ptr, "Out of Memory");
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600115
116 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600117 }
118 }
119 else
120 ret = farmalloc(size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500121
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500122 if (ret == NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500123 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600124 png_error(png_ptr, "Out of Memory");
Guy Schalnat0d580581995-07-20 02:43:20 -0500125 }
126
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600127 return ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500128}
129
130/* free a pointer allocated by png_large_malloc(). In the default
131 configuration, png_ptr is not used, but is passed in case it
132 is needed. If ptr is NULL, return without taking any action. */
133void
Guy Schalnat6d764711995-12-19 03:22:19 -0600134png_large_free(png_structp png_ptr, png_voidp ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500135{
136 if (!png_ptr)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600137 return;
138
139 if (ptr != NULL)
140 {
141 if (png_ptr->offset_table)
142 {
143 int i;
144
145 for (i = 0; i < png_ptr->offset_table_count; i++)
146 {
147 if (ptr == png_ptr->offset_table_ptr[i])
148 {
149 ptr = 0;
150 png_ptr->offset_table_count_free++;
151 break;
152 }
153 }
154 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
155 {
156 farfree(png_ptr->offset_table);
157 farfree(png_ptr->offset_table_ptr);
158 png_ptr->offset_table = 0;
159 png_ptr->offset_table_ptr = 0;
160 }
161 }
162
163 if (ptr)
164 farfree(ptr);
165 }
166}
167
168#else /* Not the Borland DOS special memory handler */
169
170/* Allocate memory. For reasonable files, size should never exceed
171 64K. However, zlib may allocate more then 64K if you don't tell
172 it not to. See zconf.h and png.h for more information. zlib does
173 need to allocate exactly 64K, so whatever you call here must
174 have the ability to do that. */
175
176
177png_voidp
178png_large_malloc(png_structp png_ptr, png_uint_32 size)
179{
180 png_voidp ret;
181 if (!png_ptr || !size)
182 return ((voidp)0);
183
184#ifdef PNG_MAX_MALLOC_64K
185 if (size > (png_uint_32)65536L)
186 png_error(png_ptr, "Cannot Allocate > 64K");
187#endif
188
189#if defined(__TURBOC__) && !defined(__FLAT__)
190 ret = farmalloc(size);
191#else
192# if defined(_MSC_VER) && defined(MAXSEG_64K)
193 ret = halloc(size, 1);
194# else
195 ret = malloc(size);
196# endif
197#endif
198
199 if (ret == NULL)
200 {
201 png_error(png_ptr, "Out of Memory");
202 }
203
204 return ret;
205}
206
207/* free a pointer allocated by png_large_malloc(). In the default
208 configuration, png_ptr is not used, but is passed in case it
209 is needed. If ptr is NULL, return without taking any action. */
210void
211png_large_free(png_structp png_ptr, png_voidp ptr)
212{
213 if (!png_ptr)
214 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500215
Guy Schalnat6d764711995-12-19 03:22:19 -0600216 if (ptr != NULL)
Guy Schalnat0d580581995-07-20 02:43:20 -0500217 {
Guy Schalnat6d764711995-12-19 03:22:19 -0600218#if defined(__TURBOC__) && !defined(__FLAT__)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600219 farfree(ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500220#else
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600221# if defined(_MSC_VER) && defined(MAXSEG_64K)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600222 hfree(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600223# else
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600224 free(ptr);
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600225# endif
Guy Schalnat0d580581995-07-20 02:43:20 -0500226#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600227 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500228}
229
Guy Schalnat4ee97b01996-01-16 01:51:56 -0600230#endif /* Not Borland DOS special memory handler */
Guy Schalnat6d764711995-12-19 03:22:19 -0600231
Guy Schalnat0d580581995-07-20 02:43:20 -0500232/* Allocate memory. This is called for smallish blocks only It
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600233 should not get anywhere near 64K. On segmented machines, this
234 must come from the local heap (for zlib). Currently, zlib is
235 the only one that uses this, so you should only get one call
236 to this, and that a small block. */
Guy Schalnat0d580581995-07-20 02:43:20 -0500237void *
Guy Schalnat6d764711995-12-19 03:22:19 -0600238png_malloc(png_structp png_ptr, png_uint_32 size)
Guy Schalnat0d580581995-07-20 02:43:20 -0500239{
240 void *ret;
241
Guy Schalnat51f0eb41995-09-26 05:22:39 -0500242 if (!png_ptr || !size)
Guy Schalnat6d764711995-12-19 03:22:19 -0600243 {
Guy Schalnat0d580581995-07-20 02:43:20 -0500244 return ((void *)0);
Guy Schalnat6d764711995-12-19 03:22:19 -0600245 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500246
247#ifdef PNG_MAX_MALLOC_64K
248 if (size > (png_uint_32)65536L)
Guy Schalnat6d764711995-12-19 03:22:19 -0600249 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat0d580581995-07-20 02:43:20 -0500250#endif
251
Guy Schalnat6d764711995-12-19 03:22:19 -0600252
Guy Schalnat0d580581995-07-20 02:43:20 -0500253 ret = malloc((png_size_t)size);
254
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600255 if (!ret)
Guy Schalnat0d580581995-07-20 02:43:20 -0500256 {
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600257 png_error(png_ptr, "Out of Memory");
Guy Schalnat0d580581995-07-20 02:43:20 -0500258 }
259
260 return ret;
261}
262
263/* Reallocate memory. This will not get near 64K on a
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600264 even marginally reasonable file. This is not used in
265 the current version of the library. */
Guy Schalnat0d580581995-07-20 02:43:20 -0500266void *
Guy Schalnat6d764711995-12-19 03:22:19 -0600267png_realloc(png_structp png_ptr, void * ptr, png_uint_32 size,
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600268 png_uint_32 old_size)
Guy Schalnat0d580581995-07-20 02:43:20 -0500269{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600270 void *ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500271
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600272 if (!png_ptr || !old_size || !ptr || !size)
273 return ((void *)0);
Guy Schalnat0d580581995-07-20 02:43:20 -0500274
275#ifdef PNG_MAX_MALLOC_64K
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600276 if (size > (png_uint_32)65536L)
277 png_error(png_ptr, "Cannot Allocate > 64K");
Guy Schalnat0d580581995-07-20 02:43:20 -0500278#endif
279
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600280 ret = realloc(ptr, (png_size_t)size);
Guy Schalnat0d580581995-07-20 02:43:20 -0500281
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600282 if (!ret)
283 {
284 png_error(png_ptr, "Out of Memory 7");
285 }
Guy Schalnat0d580581995-07-20 02:43:20 -0500286
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600287 return ret;
Guy Schalnat0d580581995-07-20 02:43:20 -0500288}
289
290/* free a pointer allocated by png_malloc(). In the default
291 configuration, png_ptr is not used, but is passed incase it
292 is needed. If ptr is NULL, return without taking any action. */
293void
Guy Schalnat6d764711995-12-19 03:22:19 -0600294png_free(png_structp png_ptr, void * ptr)
Guy Schalnat0d580581995-07-20 02:43:20 -0500295{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600296 if (!png_ptr)
297 return;
Guy Schalnat0d580581995-07-20 02:43:20 -0500298
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600299 if (ptr != (void *)0)
300 free(ptr);
Guy Schalnat0d580581995-07-20 02:43:20 -0500301}
302
Guy Schalnat6d764711995-12-19 03:22:19 -0600303