pngmem.c 9.3 KB
Newer Older
1

2
/* pngmem.c - stub functions for memory allocation
3
 *
4
 * libpng 1.0.0b
5 6 7
 * For conditions of distribution and use, see copyright notice in png.h
 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
 * Copyright (c) 1996, 1997 Andreas Dilger
8
 * Copyright (c) 1998, Glenn Randers-Pehrson
9
 * March 13, 1998
10 11 12 13 14
 *
 * This file provides a location for all memory allocation.  Users which
 * need special memory handling are expected to modify the code in this file
 * to meet their needs.  See the instructions at each function.
 */
15 16 17 18

#define PNG_INTERNAL
#include "png.h"

19 20 21
/* The following "hides" PNG_MALLOC and PNG_FREE thus allowing the pngtest
   application to put a wrapper on top of them. */
#ifdef PNGTEST_MEMORY_DEBUG
22 23
#define PNG_MALLOC png_debug_malloc
#define PNG_FREE   png_debug_free
24
#else
25 26
#define PNG_MALLOC png_malloc
#define PNG_FREE   png_free
27 28
#endif

29 30 31 32
/* Borland DOS special memory handler */
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
/* if you change this, be sure to change the one in png.h also */

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 40 41 42 43 44 45
   png_voidp struct_ptr;

   if (type == PNG_STRUCT_INFO)
     size = sizeof(png_info);
   else if (type == PNG_STRUCT_PNG)
     size = sizeof(png_struct);
   else
46
     return ((png_voidp)NULL);
47 48 49 50 51 52 53 54 55 56 57 58 59 60

   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
   {
      png_memset(struct_ptr, 0, size);
   }

   return (struct_ptr);
}


/* Free memory allocated by a png_create_struct() call */
void
png_destroy_struct(png_voidp struct_ptr)
{
61
   if (struct_ptr != NULL)
62
   {
63
      farfree (struct_ptr);
64 65
      struct_ptr = NULL;
   }
66 67
}

68
/* Allocate memory.  For reasonable files, size should never exceed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
 * 64K.  However, zlib may allocate more then 64K if you don't tell
 * it not to.  See zconf.h and png.h for more information. zlib does
 * need to allocate exactly 64K, so whatever you call here must
 * have the ability to do that.
 *
 * Borland seems to have a problem in DOS mode for exactly 64K.
 * It gives you a segment with an offset of 8 (perhaps to store it's
 * memory stuff).  zlib doesn't like this at all, so we have to
 * detect and deal with it.  This code should not be needed in
 * Windows or OS/2 modes, and only in 16 bit mode.  This code has
 * been updated by Alexander Lehmann for version 0.89 to waste less
 * memory.
 *
 * Note that we can't use png_size_t for the "size" declaration,
 * since on some systems a png_size_t is a 16-bit quantity, and as a
 * result, we would be truncating potentially larger memory requests
 * (which should cause a fatal error) and introducing major problems.
 */
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 96
   if (size > (png_uint_32)65536L)
      png_error(png_ptr, "Cannot Allocate > 64K");
97 98
#endif

99
   if (size == (png_uint_32)65536L)
100
   {
101
      if (png_ptr->offset_table == NULL)
102 103 104
      {
         /* try to see if we need to do any of this fancy stuff */
         ret = farmalloc(size);
105
         if (ret == NULL || ((png_size_t)ret & 0xffff))
106 107 108 109 110
         {
            int num_blocks;
            png_uint_32 total_size;
            png_bytep table;
            int i;
111 112
            png_byte huge * hptr;

113
            if (ret != NULL)
114
            {
115
               farfree(ret);
116 117
               ret = NULL;
            }
118 119 120 121 122 123 124 125 126

            num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
            if (num_blocks < 1)
               num_blocks = 1;
            if (png_ptr->zlib_mem_level >= 7)
               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
            else
               num_blocks++;

127
            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
128 129 130

            table = farmalloc(total_size);

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 143
            png_ptr->offset_table_ptr = farmalloc(num_blocks *
               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 154
               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
               hptr += 16L;
155 156 157 158
            }
            for (i = 0; i < num_blocks; i++)
            {
               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
159
               hptr += (png_uint_32)65536L;
160 161 162 163 164 165
            }

            png_ptr->offset_table_number = num_blocks;
            png_ptr->offset_table_count = 0;
            png_ptr->offset_table_count_free = 0;
         }
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 174
   }
   else
      ret = farmalloc(size);
175

176 177
   if (ret == NULL)
   {
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 186
   configuration, png_ptr is not used, but is passed in case it
   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 192
      return;

193
   if (png_ptr->offset_table != NULL)
194
   {
195
      int i;
196

197 198 199
      for (i = 0; i < png_ptr->offset_table_count; i++)
      {
         if (ptr == png_ptr->offset_table_ptr[i])
200
         {
201 202 203
            ptr = NULL;
            png_ptr->offset_table_count_free++;
            break;
204
         }
205
      }
206 207 208 209 210 211 212
      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
      {
         farfree(png_ptr->offset_table);
         farfree(png_ptr->offset_table_ptr);
         png_ptr->offset_table = NULL;
         png_ptr->offset_table_ptr = NULL;
      }
213
   }
214 215

   if (ptr != NULL)
216
   {
217
      farfree(ptr);
218 219
      ptr = NULL;
   }
220 221 222 223
}

#else /* Not the Borland DOS special memory handler */

224
/* Allocate memory for a png_struct or a png_info.  The malloc and
225 226
   memset can be replaced by a single call to calloc() if this is thought
   to improve performance noticably.*/
227
png_voidp
228
png_create_struct(int type)
229
{
230
   png_size_t size;
231 232 233
   png_voidp struct_ptr;

   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 241 242 243

#if defined(__TURBOC__) && !defined(__FLAT__)
   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
244
   if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
# else
   if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
# endif
#endif
   {
      png_memset(struct_ptr, 0, size);
   }

   return (struct_ptr);
}


/* Free memory allocated by a png_create_struct() call */
void
png_destroy_struct(png_voidp struct_ptr)
{
261
   if (struct_ptr != NULL)
262
   {
263 264 265 266 267 268 269 270 271
#if defined(__TURBOC__) && !defined(__FLAT__)
      farfree(struct_ptr);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
      hfree(struct_ptr);
# else
      free(struct_ptr);
# endif
#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 280
   need to allocate exactly 64K, so whatever you call here must
   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 294
#endif

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 304
#endif

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 315 316
  configuration, png_ptr is not used, but is passed in case it
  is needed.  If ptr is NULL, return without taking any action. */
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 331 332
#endif
}

333
#endif /* Not Borland DOS special memory handler */
334

335 336
png_voidp
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
337 338 339
   png_uint_32 length)
{
   png_size_t size;
340 341 342 343 344 345

   size = (png_size_t)length;
   if ((png_uint_32)size != length)
      png_error(png_ptr,"Overflow in png_memcpy_check.");
  
   return(png_memcpy (s1, s2, size));
346 347
}

348 349
png_voidp
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
350 351 352
   png_uint_32 length)
{
   png_size_t size;
353 354 355 356 357 358 359

   size = (png_size_t)length;
   if ((png_uint_32)size != length)
      png_error(png_ptr,"Overflow in png_memset_check.");

   return (png_memset (s1, value, size));

360
}
新手
引导
客服 返回
顶部