Back to index

plt-scheme  4.2.1
pngmem.c
Go to the documentation of this file.
00001 
00002 /* pngmem.c - stub functions for memory allocation
00003  *
00004  * libpng 1.2.5 - October 3, 2002
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2002 Glenn Randers-Pehrson
00007  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00008  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00009  *
00010  * This file provides a location for all memory allocation.  Users who
00011  * need special memory handling are expected to supply replacement
00012  * functions for png_malloc() and png_free(), and to use
00013  * png_create_read_struct_2() and png_create_write_struct_2() to
00014  * identify the replacement functions.
00015  */
00016 
00017 #define PNG_INTERNAL
00018 #include "png.h"
00019 
00020 /* Borland DOS special memory handler */
00021 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
00022 /* if you change this, be sure to change the one in png.h also */
00023 
00024 /* Allocate memory for a png_struct.  The malloc and memset can be replaced
00025    by a single call to calloc() if this is thought to improve performance. */
00026 png_voidp /* PRIVATE */
00027 png_create_struct(int type)
00028 {
00029 #ifdef PNG_USER_MEM_SUPPORTED
00030    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
00031 }
00032 
00033 /* Alternate version of png_create_struct, for use with user-defined malloc. */
00034 png_voidp /* PRIVATE */
00035 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
00036 {
00037 #endif /* PNG_USER_MEM_SUPPORTED */
00038    png_size_t size;
00039    png_voidp struct_ptr;
00040 
00041    if (type == PNG_STRUCT_INFO)
00042      size = sizeof(png_info);
00043    else if (type == PNG_STRUCT_PNG)
00044      size = sizeof(png_struct);
00045    else
00046      return (png_get_copyright());
00047 
00048 #ifdef PNG_USER_MEM_SUPPORTED
00049    if(malloc_fn != NULL)
00050    {
00051       png_struct dummy_struct;
00052       png_structp png_ptr = &dummy_struct;
00053       png_ptr->mem_ptr=mem_ptr;
00054       struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
00055    }
00056    else
00057 #endif /* PNG_USER_MEM_SUPPORTED */
00058       struct_ptr = (png_voidp)farmalloc(size));
00059    if (struct_ptr != NULL)
00060       png_memset(struct_ptr, 0, size);
00061    return (struct_ptr);
00062 }
00063 
00064 /* Free memory allocated by a png_create_struct() call */
00065 void /* PRIVATE */
00066 png_destroy_struct(png_voidp struct_ptr)
00067 {
00068 #ifdef PNG_USER_MEM_SUPPORTED
00069    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
00070 }
00071 
00072 /* Free memory allocated by a png_create_struct() call */
00073 void /* PRIVATE */
00074 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
00075     png_voidp mem_ptr)
00076 {
00077 #endif
00078    if (struct_ptr != NULL)
00079    {
00080 #ifdef PNG_USER_MEM_SUPPORTED
00081       if(free_fn != NULL)
00082       {
00083          png_struct dummy_struct;
00084          png_structp png_ptr = &dummy_struct;
00085          png_ptr->mem_ptr=mem_ptr;
00086          (*(free_fn))(png_ptr, struct_ptr);
00087          return;
00088       }
00089 #endif /* PNG_USER_MEM_SUPPORTED */
00090       farfree (struct_ptr);
00091    }
00092 }
00093 
00094 /* Allocate memory.  For reasonable files, size should never exceed
00095  * 64K.  However, zlib may allocate more then 64K if you don't tell
00096  * it not to.  See zconf.h and png.h for more information. zlib does
00097  * need to allocate exactly 64K, so whatever you call here must
00098  * have the ability to do that.
00099  *
00100  * Borland seems to have a problem in DOS mode for exactly 64K.
00101  * It gives you a segment with an offset of 8 (perhaps to store its
00102  * memory stuff).  zlib doesn't like this at all, so we have to
00103  * detect and deal with it.  This code should not be needed in
00104  * Windows or OS/2 modes, and only in 16 bit mode.  This code has
00105  * been updated by Alexander Lehmann for version 0.89 to waste less
00106  * memory.
00107  *
00108  * Note that we can't use png_size_t for the "size" declaration,
00109  * since on some systems a png_size_t is a 16-bit quantity, and as a
00110  * result, we would be truncating potentially larger memory requests
00111  * (which should cause a fatal error) and introducing major problems.
00112  */
00113 
00114 png_voidp PNGAPI
00115 png_malloc(png_structp png_ptr, png_uint_32 size)
00116 {
00117    png_voidp ret;
00118 
00119    if (png_ptr == NULL || size == 0)
00120       return (NULL);
00121 
00122 #ifdef PNG_USER_MEM_SUPPORTED
00123    if(png_ptr->malloc_fn != NULL)
00124    {
00125        ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
00126        if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00127           png_error(png_ptr, "Out of memory!");
00128        return (ret);
00129    }
00130    else
00131        return png_malloc_default(png_ptr, size);
00132 }
00133 
00134 png_voidp PNGAPI
00135 png_malloc_default(png_structp png_ptr, png_uint_32 size)
00136 {
00137    png_voidp ret;
00138 #endif /* PNG_USER_MEM_SUPPORTED */
00139 
00140 #ifdef PNG_MAX_MALLOC_64K
00141    if (size > (png_uint_32)65536L)
00142       png_error(png_ptr, "Cannot Allocate > 64K");
00143 #endif
00144 
00145    if (size == (png_uint_32)65536L)
00146    {
00147       if (png_ptr->offset_table == NULL)
00148       {
00149          /* try to see if we need to do any of this fancy stuff */
00150          ret = farmalloc(size);
00151          if (ret == NULL || ((png_size_t)ret & 0xffff))
00152          {
00153             int num_blocks;
00154             png_uint_32 total_size;
00155             png_bytep table;
00156             int i;
00157             png_byte huge * hptr;
00158 
00159             if (ret != NULL)
00160             {
00161                farfree(ret);
00162                ret = NULL;
00163             }
00164 
00165             if(png_ptr->zlib_window_bits > 14)
00166                num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
00167             else
00168                num_blocks = 1;
00169             if (png_ptr->zlib_mem_level >= 7)
00170                num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
00171             else
00172                num_blocks++;
00173 
00174             total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
00175 
00176             table = farmalloc(total_size);
00177 
00178             if (table == NULL)
00179             {
00180                if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00181                   png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
00182                else
00183                   png_warning(png_ptr, "Out Of Memory.");
00184                return (NULL);
00185             }
00186 
00187             if ((png_size_t)table & 0xfff0)
00188             {
00189                if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00190                   png_error(png_ptr,
00191                     "Farmalloc didn't return normalized pointer");
00192                else
00193                   png_warning(png_ptr,
00194                     "Farmalloc didn't return normalized pointer");
00195                return (NULL);
00196             }
00197 
00198             png_ptr->offset_table = table;
00199             png_ptr->offset_table_ptr = farmalloc(num_blocks *
00200                sizeof (png_bytep));
00201 
00202             if (png_ptr->offset_table_ptr == NULL)
00203             {
00204                if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00205                   png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
00206                else
00207                   png_warning(png_ptr, "Out Of memory.");
00208                return (NULL);
00209             }
00210 
00211             hptr = (png_byte huge *)table;
00212             if ((png_size_t)hptr & 0xf)
00213             {
00214                hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
00215                hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
00216             }
00217             for (i = 0; i < num_blocks; i++)
00218             {
00219                png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
00220                hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
00221             }
00222 
00223             png_ptr->offset_table_number = num_blocks;
00224             png_ptr->offset_table_count = 0;
00225             png_ptr->offset_table_count_free = 0;
00226          }
00227       }
00228 
00229       if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
00230       {
00231          if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00232             png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
00233          else
00234             png_warning(png_ptr, "Out of Memory.");
00235          return (NULL);
00236       }
00237 
00238       ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
00239    }
00240    else
00241       ret = farmalloc(size);
00242 
00243    if (ret == NULL)
00244    {
00245       if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00246          png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
00247       else
00248          png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
00249    }
00250 
00251    return (ret);
00252 }
00253 
00254 /* free a pointer allocated by png_malloc().  In the default
00255    configuration, png_ptr is not used, but is passed in case it
00256    is needed.  If ptr is NULL, return without taking any action. */
00257 void PNGAPI
00258 png_free(png_structp png_ptr, png_voidp ptr)
00259 {
00260    if (png_ptr == NULL || ptr == NULL)
00261       return;
00262 
00263 #ifdef PNG_USER_MEM_SUPPORTED
00264    if (png_ptr->free_fn != NULL)
00265    {
00266       (*(png_ptr->free_fn))(png_ptr, ptr);
00267       return;
00268    }
00269    else png_free_default(png_ptr, ptr);
00270 }
00271 
00272 void PNGAPI
00273 png_free_default(png_structp png_ptr, png_voidp ptr)
00274 {
00275 #endif /* PNG_USER_MEM_SUPPORTED */
00276 
00277    if (png_ptr->offset_table != NULL)
00278    {
00279       int i;
00280 
00281       for (i = 0; i < png_ptr->offset_table_count; i++)
00282       {
00283          if (ptr == png_ptr->offset_table_ptr[i])
00284          {
00285             ptr = NULL;
00286             png_ptr->offset_table_count_free++;
00287             break;
00288          }
00289       }
00290       if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
00291       {
00292          farfree(png_ptr->offset_table);
00293          farfree(png_ptr->offset_table_ptr);
00294          png_ptr->offset_table = NULL;
00295          png_ptr->offset_table_ptr = NULL;
00296       }
00297    }
00298 
00299    if (ptr != NULL)
00300    {
00301       farfree(ptr);
00302    }
00303 }
00304 
00305 #else /* Not the Borland DOS special memory handler */
00306 
00307 /* Allocate memory for a png_struct or a png_info.  The malloc and
00308    memset can be replaced by a single call to calloc() if this is thought
00309    to improve performance noticably. */
00310 png_voidp /* PRIVATE */
00311 png_create_struct(int type)
00312 {
00313 #ifdef PNG_USER_MEM_SUPPORTED
00314    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
00315 }
00316 
00317 /* Allocate memory for a png_struct or a png_info.  The malloc and
00318    memset can be replaced by a single call to calloc() if this is thought
00319    to improve performance noticably. */
00320 png_voidp /* PRIVATE */
00321 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
00322 {
00323 #endif /* PNG_USER_MEM_SUPPORTED */
00324    png_size_t size;
00325    png_voidp struct_ptr;
00326 
00327    if (type == PNG_STRUCT_INFO)
00328       size = sizeof(png_info);
00329    else if (type == PNG_STRUCT_PNG)
00330       size = sizeof(png_struct);
00331    else
00332       return (NULL);
00333 
00334 #ifdef PNG_USER_MEM_SUPPORTED
00335    if(malloc_fn != NULL)
00336    {
00337       png_struct dummy_struct;
00338       png_structp png_ptr = &dummy_struct;
00339       png_ptr->mem_ptr=mem_ptr;
00340       struct_ptr = (*(malloc_fn))(png_ptr, size);
00341       if (struct_ptr != NULL)
00342          png_memset(struct_ptr, 0, size);
00343       return (struct_ptr);
00344    }
00345 #endif /* PNG_USER_MEM_SUPPORTED */
00346 
00347 #if defined(__TURBOC__) && !defined(__FLAT__)
00348    if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
00349 #else
00350 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00351    if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
00352 # else
00353    if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
00354 # endif
00355 #endif
00356    {
00357       png_memset(struct_ptr, 0, size);
00358    }
00359 
00360    return (struct_ptr);
00361 }
00362 
00363 
00364 /* Free memory allocated by a png_create_struct() call */
00365 void /* PRIVATE */
00366 png_destroy_struct(png_voidp struct_ptr)
00367 {
00368 #ifdef PNG_USER_MEM_SUPPORTED
00369    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
00370 }
00371 
00372 /* Free memory allocated by a png_create_struct() call */
00373 void /* PRIVATE */
00374 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
00375     png_voidp mem_ptr)
00376 {
00377 #endif /* PNG_USER_MEM_SUPPORTED */
00378    if (struct_ptr != NULL)
00379    {
00380 #ifdef PNG_USER_MEM_SUPPORTED
00381       if(free_fn != NULL)
00382       {
00383          png_struct dummy_struct;
00384          png_structp png_ptr = &dummy_struct;
00385          png_ptr->mem_ptr=mem_ptr;
00386          (*(free_fn))(png_ptr, struct_ptr);
00387          return;
00388       }
00389 #endif /* PNG_USER_MEM_SUPPORTED */
00390 #if defined(__TURBOC__) && !defined(__FLAT__)
00391       farfree(struct_ptr);
00392 #else
00393 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00394       hfree(struct_ptr);
00395 # else
00396       free(struct_ptr);
00397 # endif
00398 #endif
00399    }
00400 }
00401 
00402 /* Allocate memory.  For reasonable files, size should never exceed
00403    64K.  However, zlib may allocate more then 64K if you don't tell
00404    it not to.  See zconf.h and png.h for more information.  zlib does
00405    need to allocate exactly 64K, so whatever you call here must
00406    have the ability to do that. */
00407 
00408 png_voidp PNGAPI
00409 png_malloc(png_structp png_ptr, png_uint_32 size)
00410 {
00411    png_voidp ret;
00412 
00413    if (png_ptr == NULL || size == 0)
00414       return (NULL);
00415 
00416 #ifdef PNG_USER_MEM_SUPPORTED
00417    if(png_ptr->malloc_fn != NULL)
00418    {
00419        ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
00420        if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00421           png_error(png_ptr, "Out of Memory!");
00422        return (ret);
00423    }
00424    else
00425        return (png_malloc_default(png_ptr, size));
00426 }
00427 
00428 png_voidp PNGAPI
00429 png_malloc_default(png_structp png_ptr, png_uint_32 size)
00430 {
00431    png_voidp ret;
00432 #endif /* PNG_USER_MEM_SUPPORTED */
00433 
00434 #ifdef PNG_MAX_MALLOC_64K
00435    if (size > (png_uint_32)65536L)
00436    {
00437       if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00438          png_error(png_ptr, "Cannot Allocate > 64K");
00439       else
00440          return NULL;
00441    }
00442 #endif
00443 
00444 #if defined(__TURBOC__) && !defined(__FLAT__)
00445    ret = farmalloc(size);
00446 #else
00447 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00448    ret = halloc(size, 1);
00449 # else
00450    ret = malloc((size_t)size);
00451 # endif
00452 #endif
00453 
00454    if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00455       png_error(png_ptr, "Out of Memory");
00456 
00457    return (ret);
00458 }
00459 
00460 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
00461    without taking any action. */
00462 void PNGAPI
00463 png_free(png_structp png_ptr, png_voidp ptr)
00464 {
00465    if (png_ptr == NULL || ptr == NULL)
00466       return;
00467 
00468 #ifdef PNG_USER_MEM_SUPPORTED
00469    if (png_ptr->free_fn != NULL)
00470    {
00471       (*(png_ptr->free_fn))(png_ptr, ptr);
00472       return;
00473    }
00474    else png_free_default(png_ptr, ptr);
00475 }
00476 void PNGAPI
00477 png_free_default(png_structp png_ptr, png_voidp ptr)
00478 {
00479    if (png_ptr == NULL || ptr == NULL)
00480       return;
00481 
00482 #endif /* PNG_USER_MEM_SUPPORTED */
00483 
00484 #if defined(__TURBOC__) && !defined(__FLAT__)
00485    farfree(ptr);
00486 #else
00487 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00488    hfree(ptr);
00489 # else
00490    free(ptr);
00491 # endif
00492 #endif
00493 }
00494 
00495 #endif /* Not Borland DOS special memory handler */
00496 
00497 #if defined(PNG_1_0_X)
00498 #  define png_malloc_warn png_malloc
00499 #else
00500 /* This function was added at libpng version 1.2.3.  The png_malloc_warn()
00501  * function will issue a png_warning and return NULL instead of issuing a
00502  * png_error, if it fails to allocate the requested memory.
00503  */
00504 png_voidp PNGAPI
00505 png_malloc_warn(png_structp png_ptr, png_uint_32 size)
00506 {
00507    png_voidp ptr;
00508    png_uint_32 save_flags=png_ptr->flags;
00509 
00510    png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
00511    ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
00512    png_ptr->flags=save_flags;
00513    return(ptr);
00514 }
00515 #endif
00516 
00517 png_voidp PNGAPI
00518 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
00519    png_uint_32 length)
00520 {
00521    png_size_t size;
00522 
00523    size = (png_size_t)length;
00524    if ((png_uint_32)size != length)
00525       png_error(png_ptr,"Overflow in png_memcpy_check.");
00526 
00527    return(png_memcpy (s1, s2, size));
00528 }
00529 
00530 png_voidp PNGAPI
00531 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
00532    png_uint_32 length)
00533 {
00534    png_size_t size;
00535 
00536    size = (png_size_t)length;
00537    if ((png_uint_32)size != length)
00538       png_error(png_ptr,"Overflow in png_memset_check.");
00539 
00540    return (png_memset (s1, value, size));
00541 
00542 }
00543 
00544 #ifdef PNG_USER_MEM_SUPPORTED
00545 /* This function is called when the application wants to use another method
00546  * of allocating and freeing memory.
00547  */
00548 void PNGAPI
00549 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
00550   malloc_fn, png_free_ptr free_fn)
00551 {
00552    png_ptr->mem_ptr = mem_ptr;
00553    png_ptr->malloc_fn = malloc_fn;
00554    png_ptr->free_fn = free_fn;
00555 }
00556 
00557 /* This function returns a pointer to the mem_ptr associated with the user
00558  * functions.  The application should free any memory associated with this
00559  * pointer before png_write_destroy and png_read_destroy are called.
00560  */
00561 png_voidp PNGAPI
00562 png_get_mem_ptr(png_structp png_ptr)
00563 {
00564    return ((png_voidp)png_ptr->mem_ptr);
00565 }
00566 #endif /* PNG_USER_MEM_SUPPORTED */