blob: ec39d7584c16576bdd27d45eb00310edfc86bb02 [file] [log] [blame] [edit]
/* pngsimd.c - hardware (cpu/arch) specific code
*
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 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
*/
#include "pngpriv.h"
#ifdef PNG_TARGET_CODE_IMPLEMENTATION
/* This is set by pngtarget.h iff there is some target code to be compiled.
*/
/* Each piece of separate hardware support code must have a "init" file defined
* in PNG_TARGET_CODE_IMPLEMENTATION and included here.
*
* The "check" header set PNG_TARGET_CODE_IMPLEMENTATION and that file *MUST*
* supply macro definitions as follows. Note that all functions must be static
* to avoid clashes with other implementations.
*
* png_target_impl
* string constant
* REQUIRED
* This must be a string naming the implemenation.
*
* png_target_free_data_impl
* static void png_target_free_data_impl(png_structrp)
* REQUIRED if PNG_TARGET_STORES_DATA is defined
* UNDEFINED if PNG_TARGET_STORES_DATA is not defined
* A function to free data stored in png_struct::target_data.
*
* png_target_init_filter_functions_impl [flag: png_target_filters]
* OPTIONAL
* Contains code to overwrite the png_struct::read_filter array, see
* the definition of png_init_filter_functions. Need not be defined,
* only called if target_state contains png_target_filters.
*
* png_target_do_expand_palette_impl [flag: png_target_expand_palette]
* static function
* OPTIONAL
* Handles the transform. Need not be defined, only called if the
* state contains png_target_<transform>, may set this flag to zero, may
* return false to indicate that the transform was not done (so the
* C implementation must then execute).
*
* Note that pngtarget.h verifies that at least one thing is implemented, the
* checks below ensure that the corresponding _impl macro is defined.
*/
/* This will fail in an obvious way with a meaningful error message if the file
* does not exist:
*/
#include PNG_TARGET_CODE_IMPLEMENTATION
#ifndef png_target_impl
# error TARGET SPECIFIC CODE: PNG_TARGET_CODE_IMPLEMENTATION is defined but\
png_hareware_impl is not
#endif
#if defined(PNG_TARGET_STORES_DATA) != defined(png_target_free_data_impl)
# error TARGET SPECIFIC CODE: png_target_free_data_impl unexpected setting
#endif
#if defined(PNG_TARGET_IMPLEMENTS_FILTERS) !=\
defined(png_target_init_filter_functions_impl)
# error TARGET SPECIFIC CODE: png_target_init_filter_functions_impl unexpected\
setting
#endif
#if defined(PNG_TARGET_IMPLEMENTS_EXPAND_PALETTE) !=\
defined(png_target_do_expand_palette_impl)
# error TARGET SPECIFIC CODE: png_target_do_expand_palette_impl unexpected\
setting
#endif
void
png_target_init(png_structrp pp)
{
/* Initialize png_struct::target_state if required. */
# ifdef png_target_init_filter_functions_impl
# define PNG_TARGET_FILTER_SUPPORT png_target_filters
# else
# define PNG_TARGET_FILTER_SUPPORT 0U
# endif
# ifdef png_target_do_expand_palette_impl
# define PNG_TARGET_EXPAND_PALETTE_SUPPORT png_target_expand_palette
# else
# define PNG_TARGET_EXPAND_PALETTE_SUPPORT 0U
# endif
# define PNG_TARGET_SUPPORT (PNG_TARGET_FILTER_SUPPORT |\
PNG_TARGET_EXPAND_PALETTE_SUPPORT)
# if PNG_TARGET_SUPPORT != 0U
pp->target_state = PNG_TARGET_SUPPORT;
# else
PNG_UNUSED(pp);
# endif
}
#ifdef PNG_TARGET_STORES_DATA
void
png_target_free_data(png_structrp pp)
{
/* Free any data allocated in the png_struct::target_data.
*/
if (pp->target_data != NULL)
{
png_target_free_data_impl(pp);
if (pp->target_data != NULL)
png_error(pp, png_target_impl ": allocated data not released");
}
}
#endif
#ifdef PNG_TARGET_IMPLEMENTS_FILTERS
void
png_target_init_filter_functions(png_structp pp, unsigned int bpp)
{
if (((pp->options >> PNG_TARGET_SPECIFIC_CODE) & 3) == PNG_OPTION_ON &&
(pp->target_state & png_target_filters) != 0)
png_target_init_filter_functions_impl(pp, bpp);
}
#endif /* filters */
#ifdef PNG_TARGET_IMPLEMENTS_EXPAND_PALETTE
int
png_target_do_expand_palette(png_structrp pp, png_row_infop rip)
/*png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) */
{
/* This is exactly like 'png_do_expand_palette' except that there is a check
* on the options and target_state:
*/
return ((pp->options >> PNG_TARGET_SPECIFIC_CODE) & 3) == PNG_OPTION_ON &&
(pp->target_state & png_target_expand_palette) != 0 &&
png_target_do_expand_palette_impl(pp, rip, pp->row_buf + 1,
pp->palette, pp->trans_alpha, pp->num_trans);
}
#endif /* EXPAND_PALETTE */
#endif /* PNG_TARGET_ARCH */