pngmem.c

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

Generated on Tue Jul 5 14:13:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1