Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
96 giacomo 1
 
2
/* pngmem.c - stub functions for memory allocation
3
 *
4
 * libpng 1.2.5 - October 3, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2002 Glenn Randers-Pehrson
7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9
 *
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.
15
 */
16
 
17
#define PNG_INTERNAL
18
#include "png.h"
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. */
26
png_voidp /* PRIVATE */
27
png_create_struct(int type)
28
{
29
#ifdef PNG_USER_MEM_SUPPORTED
30
   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
31
}
32
 
33
/* Alternate version of png_create_struct, for use with user-defined malloc. */
34
png_voidp /* PRIVATE */
35
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
36
{
37
#endif /* PNG_USER_MEM_SUPPORTED */
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_get_copyright());
47
 
48
#ifdef PNG_USER_MEM_SUPPORTED
49
   if(malloc_fn != NULL)
50
   {
51
      png_struct dummy_struct;
52
      png_structp png_ptr = &dummy_struct;
53
      png_ptr->mem_ptr=mem_ptr;
54
      struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
55
   }
56
   else
57
#endif /* PNG_USER_MEM_SUPPORTED */
58
      struct_ptr = (png_voidp)farmalloc(size));
59
   if (struct_ptr != NULL)
60
      png_memset(struct_ptr, 0, size);
61
   return (struct_ptr);
62
}
63
 
64
/* Free memory allocated by a png_create_struct() call */
65
void /* PRIVATE */
66
png_destroy_struct(png_voidp struct_ptr)
67
{
68
#ifdef PNG_USER_MEM_SUPPORTED
69
   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
70
}
71
 
72
/* Free memory allocated by a png_create_struct() call */
73
void /* PRIVATE */
74
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
75
    png_voidp mem_ptr)
76
{
77
#endif
78
   if (struct_ptr != NULL)
79
   {
80
#ifdef PNG_USER_MEM_SUPPORTED
81
      if(free_fn != NULL)
82
      {
83
         png_struct dummy_struct;
84
         png_structp png_ptr = &dummy_struct;
85
         png_ptr->mem_ptr=mem_ptr;
86
         (*(free_fn))(png_ptr, struct_ptr);
87
         return;
88
      }
89
#endif /* PNG_USER_MEM_SUPPORTED */
90
      farfree (struct_ptr);
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.
101
 * It gives you a segment with an offset of 8 (perhaps to store its
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
 */
113
 
114
png_voidp PNGAPI
115
png_malloc(png_structp png_ptr, png_uint_32 size)
116
{
117
   png_voidp ret;
118
 
119
   if (png_ptr == NULL || size == 0)
120
      return (NULL);
121
 
122
#ifdef PNG_USER_MEM_SUPPORTED
123
   if(png_ptr->malloc_fn != NULL)
124
   {
125
       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
126
       if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
127
          png_error(png_ptr, "Out of memory!");
128
       return (ret);
129
   }
130
   else
131
       return png_malloc_default(png_ptr, size);
132
}
133
 
134
png_voidp PNGAPI
135
png_malloc_default(png_structp png_ptr, png_uint_32 size)
136
{
137
   png_voidp ret;
138
#endif /* PNG_USER_MEM_SUPPORTED */
139
 
140
#ifdef PNG_MAX_MALLOC_64K
141
   if (size > (png_uint_32)65536L)
142
      png_error(png_ptr, "Cannot Allocate > 64K");
143
#endif
144
 
145
   if (size == (png_uint_32)65536L)
146
   {
147
      if (png_ptr->offset_table == NULL)
148
      {
149
         /* try to see if we need to do any of this fancy stuff */
150
         ret = farmalloc(size);
151
         if (ret == NULL || ((png_size_t)ret & 0xffff))
152
         {
153
            int num_blocks;
154
            png_uint_32 total_size;
155
            png_bytep table;
156
            int i;
157
            png_byte huge * hptr;
158
 
159
            if (ret != NULL)
160
            {
161
               farfree(ret);
162
               ret = NULL;
163
            }
164
 
165
            if(png_ptr->zlib_window_bits > 14)
166
               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
167
            else
168
               num_blocks = 1;
169
            if (png_ptr->zlib_mem_level >= 7)
170
               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
171
            else
172
               num_blocks++;
173
 
174
            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
175
 
176
            table = farmalloc(total_size);
177
 
178
            if (table == NULL)
179
            {
180
               if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
181
                  png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
182
               else
183
                  png_warning(png_ptr, "Out Of Memory.");
184
               return (NULL);
185
            }
186
 
187
            if ((png_size_t)table & 0xfff0)
188
            {
189
               if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
190
                  png_error(png_ptr,
191
                    "Farmalloc didn't return normalized pointer");
192
               else
193
                  png_warning(png_ptr,
194
                    "Farmalloc didn't return normalized pointer");
195
               return (NULL);
196
            }
197
 
198
            png_ptr->offset_table = table;
199
            png_ptr->offset_table_ptr = farmalloc(num_blocks *
200
               sizeof (png_bytep));
201
 
202
            if (png_ptr->offset_table_ptr == NULL)
203
            {
204
               if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
205
                  png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
206
               else
207
                  png_warning(png_ptr, "Out Of memory.");
208
               return (NULL);
209
            }
210
 
211
            hptr = (png_byte huge *)table;
212
            if ((png_size_t)hptr & 0xf)
213
            {
214
               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
215
               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
216
            }
217
            for (i = 0; i < num_blocks; i++)
218
            {
219
               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
220
               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
221
            }
222
 
223
            png_ptr->offset_table_number = num_blocks;
224
            png_ptr->offset_table_count = 0;
225
            png_ptr->offset_table_count_free = 0;
226
         }
227
      }
228
 
229
      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
230
      {
231
         if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
232
            png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
233
         else
234
            png_warning(png_ptr, "Out of Memory.");
235
         return (NULL);
236
      }
237
 
238
      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
239
   }
240
   else
241
      ret = farmalloc(size);
242
 
243
   if (ret == NULL)
244
   {
245
      if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
246
         png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
247
      else
248
         png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
249
   }
250
 
251
   return (ret);
252
}
253
 
254
/* free a pointer allocated by png_malloc().  In the default
255
   configuration, png_ptr is not used, but is passed in case it
256
   is needed.  If ptr is NULL, return without taking any action. */
257
void PNGAPI
258
png_free(png_structp png_ptr, png_voidp ptr)
259
{
260
   if (png_ptr == NULL || ptr == NULL)
261
      return;
262
 
263
#ifdef PNG_USER_MEM_SUPPORTED
264
   if (png_ptr->free_fn != NULL)
265
   {
266
      (*(png_ptr->free_fn))(png_ptr, ptr);
267
      return;
268
   }
269
   else png_free_default(png_ptr, ptr);
270
}
271
 
272
void PNGAPI
273
png_free_default(png_structp png_ptr, png_voidp ptr)
274
{
275
#endif /* PNG_USER_MEM_SUPPORTED */
276
 
277
   if (png_ptr->offset_table != NULL)
278
   {
279
      int i;
280
 
281
      for (i = 0; i < png_ptr->offset_table_count; i++)
282
      {
283
         if (ptr == png_ptr->offset_table_ptr[i])
284
         {
285
            ptr = NULL;
286
            png_ptr->offset_table_count_free++;
287
            break;
288
         }
289
      }
290
      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
291
      {
292
         farfree(png_ptr->offset_table);
293
         farfree(png_ptr->offset_table_ptr);
294
         png_ptr->offset_table = NULL;
295
         png_ptr->offset_table_ptr = NULL;
296
      }
297
   }
298
 
299
   if (ptr != NULL)
300
   {
301
      farfree(ptr);
302
   }
303
}
304
 
305
#else /* Not the Borland DOS special memory handler */
306
 
307
/* Allocate memory for a png_struct or a png_info.  The malloc and
308
   memset can be replaced by a single call to calloc() if this is thought
309
   to improve performance noticably. */
310
png_voidp /* PRIVATE */
311
png_create_struct(int type)
312
{
313
#ifdef PNG_USER_MEM_SUPPORTED
314
   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
315
}
316
 
317
/* Allocate memory for a png_struct or a png_info.  The malloc and
318
   memset can be replaced by a single call to calloc() if this is thought
319
   to improve performance noticably. */
320
png_voidp /* PRIVATE */
321
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
322
{
323
#endif /* PNG_USER_MEM_SUPPORTED */
324
   png_size_t size;
325
   png_voidp struct_ptr;
326
 
327
   if (type == PNG_STRUCT_INFO)
328
      size = sizeof(png_info);
329
   else if (type == PNG_STRUCT_PNG)
330
      size = sizeof(png_struct);
331
   else
332
      return (NULL);
333
 
334
#ifdef PNG_USER_MEM_SUPPORTED
335
   if(malloc_fn != NULL)
336
   {
337
      png_struct dummy_struct;
338
      png_structp png_ptr = &dummy_struct;
339
      png_ptr->mem_ptr=mem_ptr;
340
      struct_ptr = (*(malloc_fn))(png_ptr, size);
341
      if (struct_ptr != NULL)
342
         png_memset(struct_ptr, 0, size);
343
      return (struct_ptr);
344
   }
345
#endif /* PNG_USER_MEM_SUPPORTED */
346
 
347
#if defined(__TURBOC__) && !defined(__FLAT__)
348
   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
349
#else
350
# if defined(_MSC_VER) && defined(MAXSEG_64K)
351
   if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
352
# else
353
   if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
354
# endif
355
#endif
356
   {
357
      png_memset(struct_ptr, 0, size);
358
   }
359
 
360
   return (struct_ptr);
361
}
362
 
363
 
364
/* Free memory allocated by a png_create_struct() call */
365
void /* PRIVATE */
366
png_destroy_struct(png_voidp struct_ptr)
367
{
368
#ifdef PNG_USER_MEM_SUPPORTED
369
   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
370
}
371
 
372
/* Free memory allocated by a png_create_struct() call */
373
void /* PRIVATE */
374
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
375
    png_voidp mem_ptr)
376
{
377
#endif /* PNG_USER_MEM_SUPPORTED */
378
   if (struct_ptr != NULL)
379
   {
380
#ifdef PNG_USER_MEM_SUPPORTED
381
      if(free_fn != NULL)
382
      {
383
         png_struct dummy_struct;
384
         png_structp png_ptr = &dummy_struct;
385
         png_ptr->mem_ptr=mem_ptr;
386
         (*(free_fn))(png_ptr, struct_ptr);
387
         return;
388
      }
389
#endif /* PNG_USER_MEM_SUPPORTED */
390
#if defined(__TURBOC__) && !defined(__FLAT__)
391
      farfree(struct_ptr);
392
#else
393
# if defined(_MSC_VER) && defined(MAXSEG_64K)
394
      hfree(struct_ptr);
395
# else
396
      free(struct_ptr);
397
# endif
398
#endif
399
   }
400
}
401
 
402
/* Allocate memory.  For reasonable files, size should never exceed
403
   64K.  However, zlib may allocate more then 64K if you don't tell
404
   it not to.  See zconf.h and png.h for more information.  zlib does
405
   need to allocate exactly 64K, so whatever you call here must
406
   have the ability to do that. */
407
 
408
png_voidp PNGAPI
409
png_malloc(png_structp png_ptr, png_uint_32 size)
410
{
411
   png_voidp ret;
412
 
413
   if (png_ptr == NULL || size == 0)
414
      return (NULL);
415
 
416
#ifdef PNG_USER_MEM_SUPPORTED
417
   if(png_ptr->malloc_fn != NULL)
418
   {
419
       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
420
       if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
421
          png_error(png_ptr, "Out of Memory!");
422
       return (ret);
423
   }
424
   else
425
       return (png_malloc_default(png_ptr, size));
426
}
427
 
428
png_voidp PNGAPI
429
png_malloc_default(png_structp png_ptr, png_uint_32 size)
430
{
431
   png_voidp ret;
432
#endif /* PNG_USER_MEM_SUPPORTED */
433
 
434
#ifdef PNG_MAX_MALLOC_64K
435
   if (size > (png_uint_32)65536L)
436
   {
437
      if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
438
         png_error(png_ptr, "Cannot Allocate > 64K");
439
      else
440
         return NULL;
441
   }
442
#endif
443
 
444
#if defined(__TURBOC__) && !defined(__FLAT__)
445
   ret = farmalloc(size);
446
#else
447
# if defined(_MSC_VER) && defined(MAXSEG_64K)
448
   ret = halloc(size, 1);
449
# else
450
   ret = malloc((size_t)size);
451
# endif
452
#endif
453
 
454
   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
455
      png_error(png_ptr, "Out of Memory");
456
 
457
   return (ret);
458
}
459
 
460
/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
461
   without taking any action. */
462
void PNGAPI
463
png_free(png_structp png_ptr, png_voidp ptr)
464
{
465
   if (png_ptr == NULL || ptr == NULL)
466
      return;
467
 
468
#ifdef PNG_USER_MEM_SUPPORTED
469
   if (png_ptr->free_fn != NULL)
470
   {
471
      (*(png_ptr->free_fn))(png_ptr, ptr);
472
      return;
473
   }
474
   else png_free_default(png_ptr, ptr);
475
}
476
void PNGAPI
477
png_free_default(png_structp png_ptr, png_voidp ptr)
478
{
479
   if (png_ptr == NULL || ptr == NULL)
480
      return;
481
 
482
#endif /* PNG_USER_MEM_SUPPORTED */
483
 
484
#if defined(__TURBOC__) && !defined(__FLAT__)
485
   farfree(ptr);
486
#else
487
# if defined(_MSC_VER) && defined(MAXSEG_64K)
488
   hfree(ptr);
489
# else
490
   free(ptr);
491
# endif
492
#endif
493
}
494
 
495
#endif /* Not Borland DOS special memory handler */
496
 
497
#if defined(PNG_1_0_X)
498
#  define png_malloc_warn png_malloc
499
#else
500
/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
501
 * function will issue a png_warning and return NULL instead of issuing a
502
 * png_error, if it fails to allocate the requested memory.
503
 */
504
png_voidp PNGAPI
505
png_malloc_warn(png_structp png_ptr, png_uint_32 size)
506
{
507
   png_voidp ptr;
508
   png_uint_32 save_flags=png_ptr->flags;
509
 
510
   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
511
   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
512
   png_ptr->flags=save_flags;
513
   return(ptr);
514
}
515
#endif
516
 
517
png_voidp PNGAPI
518
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
519
   png_uint_32 length)
520
{
521
   png_size_t size;
522
 
523
   size = (png_size_t)length;
524
   if ((png_uint_32)size != length)
525
      png_error(png_ptr,"Overflow in png_memcpy_check.");
526
 
527
   return(png_memcpy (s1, s2, size));
528
}
529
 
530
png_voidp PNGAPI
531
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
532
   png_uint_32 length)
533
{
534
   png_size_t size;
535
 
536
   size = (png_size_t)length;
537
   if ((png_uint_32)size != length)
538
      png_error(png_ptr,"Overflow in png_memset_check.");
539
 
540
   return (png_memset (s1, value, size));
541
 
542
}
543
 
544
#ifdef PNG_USER_MEM_SUPPORTED
545
/* This function is called when the application wants to use another method
546
 * of allocating and freeing memory.
547
 */
548
void PNGAPI
549
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
550
  malloc_fn, png_free_ptr free_fn)
551
{
552
   png_ptr->mem_ptr = mem_ptr;
553
   png_ptr->malloc_fn = malloc_fn;
554
   png_ptr->free_fn = free_fn;
555
}
556
 
557
/* This function returns a pointer to the mem_ptr associated with the user
558
 * functions.  The application should free any memory associated with this
559
 * pointer before png_write_destroy and png_read_destroy are called.
560
 */
561
png_voidp PNGAPI
562
png_get_mem_ptr(png_structp png_ptr)
563
{
564
   return ((png_voidp)png_ptr->mem_ptr);
565
}
566
#endif /* PNG_USER_MEM_SUPPORTED */