fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

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