1
0
mirror of https://github.com/glennrp/libpng.git synced 2026-10-24 08:39:18 +03:00
Files
libpng/pngmem.c
Cosmin Truta d9e9c6d3a0 refactor: Replace deprecated pointer typedefs (part 2)
Following up on commit 7c67f70da1:

Replace 22 deprecated pointer typedefs with their underlying types.
The typedefs replaced are:

1. Core structure types:
   - png_structp, png_structrp, png_structpp and const variants
   - png_infop, png_inforp, png_infopp and const variants

2. Utility structure types:
   - png_row_infop, png_row_infopp
   - png_imagep, png_imagepp
   - png_controlp

3. Color structure types:
   - png_colorp, png_colorpp and const variants
   - png_color_8p, png_color_8pp and const variants
   - png_color_16p, png_color_16pp and const variants

4. Text and time structure types:
   - png_textp, png_textpp and const variants
   - png_timep, png_timepp and const variants

5. Chunk structure types:
   - png_unknown_chunkp, png_unknown_chunkpp and const variants
   - png_sPLT_tp, png_sPLT_tpp and const variants
   - png_sPLT_entryp, png_sPLT_entrypp and const variants

6. Internal types:
   - png_compression_bufferp
   - png_dsortp, png_dsortpp

Remove all remaining uses of spurious PNG_RESTRICT qualifiers.
Non-aliasing has already been guaranteed by the type-based aliasing
rules combined with the libpng usage pattern of a single pointer per
type.

Update the user manual accordingly.

This completes the systematic replacement of deprecated pointer
typedefs across the entire libpng codebase. The typedef declarations
remain in png.h for backward compatibility, marked as deprecated.

Reviewed-by: Chris Blume <ProgramMax@gmail.com>
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-11-03 10:30:49 +02:00

288 lines
8.2 KiB
C

/* pngmem.c - stub functions for memory allocation
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file provides a location for all memory allocation. Users who
* need special memory handling are expected to supply replacement
* functions for png_malloc() and png_free(), and to use
* png_create_read_struct_2() and png_create_write_struct_2() to
* identify the replacement functions.
*/
#include "pngpriv.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Free a png_struct */
void /* PRIVATE */
png_destroy_png_struct(png_struct *png_ptr)
{
if (png_ptr != NULL)
{
/* png_free might call png_error and may certainly call
* png_get_mem_ptr, so fake a temporary png_struct to support this.
*/
png_struct dummy_struct = *png_ptr;
memset(png_ptr, 0, (sizeof *png_ptr));
png_free(&dummy_struct, png_ptr);
# ifdef PNG_SETJMP_SUPPORTED
/* We may have a jmp_buf left to deallocate. */
png_free_jmpbuf(&dummy_struct);
# endif
}
}
/* Allocate memory. For reasonable files, size should never exceed
* 64K. However, zlib may allocate more than 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.
*/
PNG_FUNCTION(void *,
png_calloc,(const png_struct *png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
{
void *ret;
ret = png_malloc(png_ptr, size);
if (ret != NULL)
memset(ret, 0, size);
return ret;
}
/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
* allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
* Checking and error handling must happen outside this routine; it returns NULL
* if the allocation cannot be done (for any reason.)
*/
PNG_FUNCTION(void * /* PRIVATE */,
png_malloc_base,(const png_struct *png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
{
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
* allocators have also been removed in 1.6.0, so any 16-bit system now has
* to implement a user memory handler. This checks to be sure it isn't
* called with big numbers.
*/
# ifdef PNG_MAX_MALLOC_64K
/* This is support for legacy systems which had segmented addressing
* limiting the maximum allocation size to 65536. It takes precedence
* over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems.
*
* TODO: libpng-1.8: finally remove both cases.
*/
if (size > 65536U) return NULL;
# endif
/* This is checked too because the system malloc call below takes a (size_t).
*/
if (size > PNG_SIZE_MAX) return NULL;
# ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
return png_ptr->malloc_fn(png_constcast(png_struct *,png_ptr), size);
# else
PNG_UNUSED(png_ptr)
# endif
/* Use the system malloc */
return malloc((size_t)/*SAFE*/size); /* checked for truncation above */
}
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
* that arises because of the checks in png_realloc_array that are repeated in
* png_malloc_array.
*/
static void *
png_malloc_array_checked(const png_struct *png_ptr, int nelements,
size_t element_size)
{
png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
if (req <= PNG_SIZE_MAX/element_size)
return png_malloc_base(png_ptr, req * element_size);
/* The failure case when the request is too large */
return NULL;
}
PNG_FUNCTION(void * /* PRIVATE */,
png_malloc_array,(const png_struct *png_ptr, int nelements,
size_t element_size),
PNG_ALLOCATED)
{
if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc");
return png_malloc_array_checked(png_ptr, nelements, element_size);
}
PNG_FUNCTION(void * /* PRIVATE */,
png_realloc_array,(const png_struct *png_ptr, const void *old_array,
int old_elements, int add_elements, size_t element_size),
PNG_ALLOCATED)
{
/* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
(old_array == NULL && old_elements > 0))
png_error(png_ptr, "internal error: array realloc");
/* Check for overflow on the elements count (so the caller does not have to
* check.)
*/
if (add_elements <= INT_MAX - old_elements)
{
void *new_array = png_malloc_array_checked(png_ptr,
old_elements+add_elements, element_size);
if (new_array != NULL)
{
/* Because png_malloc_array worked the size calculations below cannot
* overflow.
*/
if (old_elements > 0)
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
element_size*(unsigned)add_elements);
return new_array;
}
}
return NULL; /* error */
}
#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
/* Various functions that have different error handling are derived from this.
* png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
* function png_malloc_default is also provided.
*/
PNG_FUNCTION(void *,
png_malloc,(const png_struct *png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
{
void *ret;
if (png_ptr == NULL)
return NULL;
ret = png_malloc_base(png_ptr, size);
if (ret == NULL)
png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
return ret;
}
#ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(void *,
png_malloc_default,(const png_struct *png_ptr, png_alloc_size_t size),
PNG_ALLOCATED PNG_DEPRECATED)
{
void *ret;
if (png_ptr == NULL)
return NULL;
/* Passing 'NULL' here bypasses the application provided memory handler. */
ret = png_malloc_base(NULL/*use malloc*/, size);
if (ret == NULL)
png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
return ret;
}
#endif /* USER_MEM */
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
* function will issue a png_warning and return NULL instead of issuing a
* png_error, if it fails to allocate the requested memory.
*/
PNG_FUNCTION(void *,
png_malloc_warn,(const png_struct *png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
{
if (png_ptr != NULL)
{
void *ret = png_malloc_base(png_ptr, size);
if (ret != NULL)
return ret;
png_warning(png_ptr, "Out of memory");
}
return NULL;
}
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
* without taking any action.
*/
void
png_free(const png_struct *png_ptr, void *ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
png_ptr->free_fn(png_constcast(png_struct *,png_ptr), ptr);
else
png_free_default(png_ptr, ptr);
}
PNG_FUNCTION(void,
png_free_default,(const png_struct *png_ptr, void *ptr),
PNG_DEPRECATED)
{
if (png_ptr == NULL || ptr == NULL)
return;
#endif /* USER_MEM */
free(ptr);
}
#ifdef PNG_USER_MEM_SUPPORTED
/* This function is called when the application wants to use another method
* of allocating and freeing memory.
*/
void
png_set_mem_fn(png_struct *png_ptr, void *mem_ptr,
png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
if (png_ptr != NULL)
{
png_ptr->mem_ptr = mem_ptr;
png_ptr->malloc_fn = malloc_fn;
png_ptr->free_fn = free_fn;
}
}
/* This function returns a pointer to the mem_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
void *
png_get_mem_ptr(const png_struct *png_ptr)
{
if (png_ptr == NULL)
return NULL;
return png_ptr->mem_ptr;
}
#endif /* USER_MEM */
#endif /* READ || WRITE */