pngmem.c 8.0 KB
Newer Older
G
Guy Schalnat 已提交
1

G
Guy Schalnat 已提交
2
/* pngmem.c - stub functions for memory allocation
G
Guy Schalnat 已提交
3

A
Andreas Dilger 已提交
4
   libpng 1.0 beta 4 - version 0.90
G
Guy Schalnat 已提交
5
   For conditions of distribution and use, see copyright notice in png.h
G
Guy Schalnat 已提交
6
   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
A
Andreas Dilger 已提交
7
   January 10, 1997
G
Guy Schalnat 已提交
8

G
Guy Schalnat 已提交
9
   This file provides a location for all memory allocation.  Users which
G
Guy Schalnat 已提交
10 11
   need special memory handling are expected to modify the code in this file
   to meet their needs.  See the instructions at each function. */
G
Guy Schalnat 已提交
12 13 14 15

#define PNG_INTERNAL
#include "png.h"

G
Guy Schalnat 已提交
16 17 18 19
/* 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 */

G
Guy Schalnat 已提交
20
/* Allocate memory for a png_struct.  The malloc and memset can be replaced
A
Andreas Dilger 已提交
21
   by a single call to calloc() if this is thought to improve performance. */
G
Guy Schalnat 已提交
22
png_voidp
A
Andreas Dilger 已提交
23
png_create_struct(int type)
G
Guy Schalnat 已提交
24
{
A
Andreas Dilger 已提交
25
   png_size_t size;
G
Guy Schalnat 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
   png_voidp struct_ptr;

   if (type == PNG_STRUCT_INFO)
     size = sizeof(png_info);
   else if (type == PNG_STRUCT_PNG)
     size = sizeof(png_struct);
   else
     return (png_voidp)NULL;

   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)
{
   if (struct_ptr)
      farfree (struct_ptr);
}

G
Guy Schalnat 已提交
52
/* Allocate memory.  For reasonable files, size should never exceed
G
Guy Schalnat 已提交
53 54 55 56
   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. */
G
Guy Schalnat 已提交
57

G
Guy Schalnat 已提交
58
/* Borland seems to have a problem in DOS mode for exactly 64K.
G
Guy Schalnat 已提交
59 60 61
   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
G
Guy Schalnat 已提交
62 63 64
   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.
G
Guy Schalnat 已提交
65
*/
G
Guy Schalnat 已提交
66

G
Guy Schalnat 已提交
67
png_voidp
A
Andreas Dilger 已提交
68
png_malloc(png_structp png_ptr, png_uint_32 size)
G
Guy Schalnat 已提交
69
{
G
Guy Schalnat 已提交
70 71
   png_voidp ret;
   if (!png_ptr || !size)
G
Guy Schalnat 已提交
72
      return ((voidp)NULL);
G
Guy Schalnat 已提交
73 74

#ifdef PNG_MAX_MALLOC_64K
G
Guy Schalnat 已提交
75 76
   if (size > (png_uint_32)65536L)
      png_error(png_ptr, "Cannot Allocate > 64K");
G
Guy Schalnat 已提交
77 78
#endif

G
Guy Schalnat 已提交
79 80 81 82 83 84 85 86 87 88 89 90
   if (size == (png_uint_32)(65536L))
   {
      if (!png_ptr->offset_table)
      {
         /* try to see if we need to do any of this fancy stuff */
         ret = farmalloc(size);
         if (!ret || ((long)ret & 0xffff))
         {
            int num_blocks;
            png_uint_32 total_size;
            png_bytep table;
            int i;
G
Guy Schalnat 已提交
91 92
            png_byte huge * hptr;

G
Guy Schalnat 已提交
93 94
            if (ret)
               farfree(ret);
G
Guy Schalnat 已提交
95
            ret = NULL;
G
Guy Schalnat 已提交
96 97 98 99 100 101 102 103 104

            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++;

G
Guy Schalnat 已提交
105
            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
G
Guy Schalnat 已提交
106 107 108 109 110 111 112 113

            table = farmalloc(total_size);

            if (!table)
            {
               png_error(png_ptr, "Out of Memory");
            }

G
Guy Schalnat 已提交
114
            if ((long)table & 0xfff0)
G
Guy Schalnat 已提交
115
            {
G
Guy Schalnat 已提交
116
               png_error(png_ptr, "Farmalloc didn't return normalized pointer");
G
Guy Schalnat 已提交
117 118
            }

G
Guy Schalnat 已提交
119 120 121
            png_ptr->offset_table = table;
            png_ptr->offset_table_ptr = farmalloc(
               num_blocks * sizeof (png_bytep));
G
Guy Schalnat 已提交
122

G
Guy Schalnat 已提交
123
            if (!png_ptr->offset_table_ptr)
G
Guy Schalnat 已提交
124
            {
G
Guy Schalnat 已提交
125
               png_error(png_ptr, "Out of memory");
G
Guy Schalnat 已提交
126 127 128
            }

            hptr = (png_byte huge *)table;
G
Guy Schalnat 已提交
129
            if ((long)hptr & 0xf)
G
Guy Schalnat 已提交
130
            {
G
Guy Schalnat 已提交
131 132
               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
               hptr += 16L;
G
Guy Schalnat 已提交
133 134 135 136 137 138 139 140 141 142 143
            }
            for (i = 0; i < num_blocks; i++)
            {
               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
               hptr += 65536L;
            }

            png_ptr->offset_table_number = num_blocks;
            png_ptr->offset_table_count = 0;
            png_ptr->offset_table_count_free = 0;
         }
G
Guy Schalnat 已提交
144
      }
G
Guy Schalnat 已提交
145

G
Guy Schalnat 已提交
146 147
      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
         png_error(png_ptr, "Out of Memory");
G
Guy Schalnat 已提交
148

G
Guy Schalnat 已提交
149
      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
G
Guy Schalnat 已提交
150 151 152
   }
   else
      ret = farmalloc(size);
G
Guy Schalnat 已提交
153

G
Guy Schalnat 已提交
154 155 156 157
   if (ret == NULL)
   {
      png_error(png_ptr, "Out of Memory");
   }
G
Guy Schalnat 已提交
158

G
Guy Schalnat 已提交
159
   return ret;
G
Guy Schalnat 已提交
160 161
}

A
Andreas Dilger 已提交
162 163 164
/* free a pointer allocated by png_malloc().  In the default
   configuration, png_ptr is not used, but is passed in case it
   is needed.  If ptr is NULL, return without taking any action. */
G
Guy Schalnat 已提交
165
void
A
Andreas Dilger 已提交
166
png_free(png_structp png_ptr, png_voidp ptr)
G
Guy Schalnat 已提交
167
{
G
Guy Schalnat 已提交
168 169 170 171 172 173 174 175 176 177 178 179
   if (!png_ptr)
      return;

   if (ptr != NULL)
   {
      if (png_ptr->offset_table)
      {
         int i;

         for (i = 0; i < png_ptr->offset_table_count; i++)
         {
            if (ptr == png_ptr->offset_table_ptr[i])
G
Guy Schalnat 已提交
180
            {
G
Guy Schalnat 已提交
181
               ptr = 0;
G
Guy Schalnat 已提交
182
               png_ptr->offset_table_count_free++;
G
Guy Schalnat 已提交
183 184 185 186 187 188 189 190 191
               break;
            }
         }
         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 = 0;
            png_ptr->offset_table_ptr = 0;
G
Guy Schalnat 已提交
192
         }
G
Guy Schalnat 已提交
193
      }
G
Guy Schalnat 已提交
194

G
Guy Schalnat 已提交
195 196 197
      if (ptr)
         farfree(ptr);
   }
G
Guy Schalnat 已提交
198 199 200 201
}

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

G
Guy Schalnat 已提交
202
/* Allocate memory for a png_struct or a png_info.  The malloc and
A
Andreas Dilger 已提交
203 204
   memset can be replaced by a single call to calloc() if this is thought
   to improve performance noticably.*/
G
Guy Schalnat 已提交
205
png_voidp
A
Andreas Dilger 已提交
206
png_create_struct(int type)
G
Guy Schalnat 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
{
   size_t size;
   png_voidp struct_ptr;

   if (type == PNG_STRUCT_INFO)
     size = sizeof(png_info);
   else if (type == PNG_STRUCT_PNG)
     size = sizeof(png_struct);
   else
     return (png_voidp)NULL;

#if defined(__TURBOC__) && !defined(__FLAT__)
   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
G
Guy Schalnat 已提交
222
   if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
G
Guy Schalnat 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
# 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)
{
   if (struct_ptr)
#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
}


G
Guy Schalnat 已提交
252
/* Allocate memory.  For reasonable files, size should never exceed
G
Guy Schalnat 已提交
253 254 255 256
   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. */
G
Guy Schalnat 已提交
257

A
Andreas Dilger 已提交
258
#ifndef FORTIFY
G
Guy Schalnat 已提交
259
png_voidp
A
Andreas Dilger 已提交
260
png_malloc(png_structp png_ptr, png_uint_32 size)
G
Guy Schalnat 已提交
261
{
G
Guy Schalnat 已提交
262 263 264
   png_voidp ret;
   if (!png_ptr || !size)
      return ((voidp)0);
G
Guy Schalnat 已提交
265 266

#ifdef PNG_MAX_MALLOC_64K
G
Guy Schalnat 已提交
267 268
   if (size > (png_uint_32)65536L)
      png_error(png_ptr, "Cannot Allocate > 64K");
G
Guy Schalnat 已提交
269 270
#endif

G
Guy Schalnat 已提交
271
#if defined(__TURBOC__) && !defined(__FLAT__)
G
Guy Schalnat 已提交
272
   ret = farmalloc(size);
G
Guy Schalnat 已提交
273
#else
G
Guy Schalnat 已提交
274
# if defined(_MSC_VER) && defined(MAXSEG_64K)
G
Guy Schalnat 已提交
275
   ret = halloc(size, 1);
G
Guy Schalnat 已提交
276
# else
G
Guy Schalnat 已提交
277
   ret = malloc(size);
G
Guy Schalnat 已提交
278
# endif
G
Guy Schalnat 已提交
279 280
#endif

G
Guy Schalnat 已提交
281
   if (ret == NULL)
G
Guy Schalnat 已提交
282
   {
G
Guy Schalnat 已提交
283
      png_error(png_ptr, "Out of Memory");
G
Guy Schalnat 已提交
284 285
   }

G
Guy Schalnat 已提交
286
   return ret;
G
Guy Schalnat 已提交
287 288
}

A
Andreas Dilger 已提交
289
/* free a pointer allocated by png_malloc().  In the default
G
Guy Schalnat 已提交
290 291 292
  configuration, png_ptr is not used, but is passed in case it
  is needed.  If ptr is NULL, return without taking any action. */
void
A
Andreas Dilger 已提交
293
png_free(png_structp png_ptr, png_voidp ptr)
G
Guy Schalnat 已提交
294 295
{
   if (!png_ptr)
G
Guy Schalnat 已提交
296
      return;
G
Guy Schalnat 已提交
297

G
Guy Schalnat 已提交
298
   if (ptr != NULL)
G
Guy Schalnat 已提交
299
   {
G
Guy Schalnat 已提交
300
#if defined(__TURBOC__) && !defined(__FLAT__)
G
Guy Schalnat 已提交
301
      farfree(ptr);
G
Guy Schalnat 已提交
302
#else
G
Guy Schalnat 已提交
303
# if defined(_MSC_VER) && defined(MAXSEG_64K)
G
Guy Schalnat 已提交
304
      hfree(ptr);
G
Guy Schalnat 已提交
305
# else
G
Guy Schalnat 已提交
306
      free(ptr);
G
Guy Schalnat 已提交
307
# endif
G
Guy Schalnat 已提交
308
#endif
G
Guy Schalnat 已提交
309
   }
G
Guy Schalnat 已提交
310 311
}

A
Andreas Dilger 已提交
312
#endif /* FORTIFY */
G
Guy Schalnat 已提交
313
#endif /* Not Borland DOS special memory handler */
G
Guy Schalnat 已提交
314