shithub: libsamplerate

Download patch

ref: 36dfd68836a185182775a0ca760dd2bbbcd53e30
parent: 8a83ad3cca8596b34ff0d0faadd0d7b5c801faea
author: evpobr <evpobr@gmail.com>
date: Tue Oct 27 17:47:48 EDT 2020

Reduce usage of flexible array fields

--- a/src/src_linear.c
+++ b/src/src_linear.c
@@ -31,7 +31,7 @@
 	bool	dirty ;
 	long	in_count, in_used ;
 	long	out_count, out_gen ;
-	float	last_value [] ;
+	float	*last_value ;
 } LINEAR_DATA ;
 
 /*----------------------------------------------------------------------------------------
@@ -160,7 +160,8 @@
 
 enum SRC_ERR
 linear_set_converter (SRC_STATE *state, int src_enum)
-{	LINEAR_DATA *priv = NULL ;
+{
+	LINEAR_DATA *priv = NULL ;
 
 	if (src_enum != SRC_LINEAR)
 		return SRC_ERR_BAD_CONVERTER ;
@@ -168,13 +169,24 @@
 	linear_close (state) ;
 
 	if (state->private_data == NULL)
-	{	priv = ZERO_ALLOC (LINEAR_DATA, sizeof (*priv) + state->channels * sizeof (float)) ;
-		state->private_data = priv ;
-		} ;
+	{
+		priv = ZERO_ALLOC (ZOH_DATA, sizeof (*priv)) ;
+		if (priv)
+		{
+			priv->last_value = calloc (state->channels, sizeof (float)) ;
+			if (!priv->last_value)
+			{
+				free (priv) ;
+				priv = NULL ;
+			}
+		}
+	}
 
 	if (priv == NULL)
 		return SRC_ERR_MALLOC_FAILED ;
 
+	state->private_data = priv ;
+
 	priv->linear_magic_marker = LINEAR_MAGIC_MARKER ;
 
 	state->const_process = linear_vari_process ;
@@ -213,12 +225,18 @@
 
 	LINEAR_DATA *to_priv = NULL ;
 	LINEAR_DATA* from_priv = (LINEAR_DATA*) from->private_data ;
-	size_t private_size = sizeof (*to_priv) + from->channels * sizeof (float) ;
+	if ((to_priv = ZERO_ALLOC (LINEAR_DATA, sizeof (LINEAR_DATA))) == NULL)
+		return SRC_ERR_MALLOC_FAILED ;
 
-	if ((to_priv = ZERO_ALLOC (LINEAR_DATA, private_size)) == NULL)
+	memcpy (to_priv, from_priv, sizeof (LINEAR_DATA)) ;
+	to_priv->last_value = malloc (sizeof (float) * from->channels) ;
+	if (!to_priv->last_value)
+	{
+		free (to_priv) ;
 		return SRC_ERR_MALLOC_FAILED ;
+	}
+	memcpy (to_priv->last_value, from_priv->last_value, sizeof (float) * from->channels) ;
 
-	memcpy (to_priv, from_priv, private_size) ;
 	to->private_data = to_priv ;
 
 	return SRC_ERR_NO_ERROR ;
@@ -229,10 +247,15 @@
 {
 	if (state)
 	{
-		if (state->private_data)
+		LINEAR_DATA *linear = (LINEAR_DATA *) state->private_data ;
+		if (linear)
 		{
-			free (state->private_data) ;
-			state->private_data = NULL ;
+			if (linear->last_value)
+			{	free (linear->last_value) ;
+				linear->last_value = NULL ;
+				} ;
+			free (linear) ;
+			linear = NULL ;
 		}
 	}
 } /* linear_close */
--- a/src/src_sinc.c
+++ b/src/src_sinc.c
@@ -53,8 +53,7 @@
 	/* Sure hope noone does more than 128 channels at once. */
 	double left_calc [128], right_calc [128] ;
 
-	/* C99 struct flexible array. */
-	float	buffer [] ;
+	float	*buffer ;
 } SINC_FILTER ;
 
 static enum SRC_ERR sinc_multichan_vari_process (SRC_STATE *state, SRC_DATA *data) ;
@@ -220,10 +219,16 @@
 	temp_filter.b_len *= state->channels ;
 	temp_filter.b_len += 1 ; // There is a <= check against samples_in_hand requiring a buffer bigger than the calculation above
 
-	if ((filter = ZERO_ALLOC (SINC_FILTER, sizeof (SINC_FILTER) + sizeof (filter->buffer [0]) * (temp_filter.b_len + state->channels))) == NULL)
+	if ((filter = ZERO_ALLOC (SINC_FILTER, sizeof (SINC_FILTER))) == NULL)
 		return SRC_ERR_MALLOC_FAILED ;
 
 	*filter = temp_filter ;
+	filter->buffer = calloc (temp_filter.b_len + state->channels, sizeof (float)) ;
+	if (!filter->buffer)
+	{	free (filter) ;
+		return SRC_ERR_MALLOC_FAILED ;
+		} ;
+
 	memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
 
 	state->private_data = filter ;
@@ -267,12 +272,18 @@
 
 	SINC_FILTER *to_filter = NULL ;
 	SINC_FILTER* from_filter = (SINC_FILTER*) from->private_data ;
-	size_t private_length = sizeof (SINC_FILTER) + sizeof (from_filter->buffer [0]) * (from_filter->b_len + from->channels) ;
 
-	if ((to_filter = ZERO_ALLOC (SINC_FILTER, private_length)) == NULL)
+	if ((to_filter = ZERO_ALLOC (SINC_FILTER, sizeof (SINC_FILTER))) == NULL)
 		return SRC_ERR_MALLOC_FAILED ;
+	memcpy (to_filter, from_filter, sizeof (SINC_FILTER)) ;
+	to_filter->buffer = malloc (sizeof (float) * (from_filter->b_len + from->channels)) ;
+	if (!to_filter->buffer)
+	{
+		free (to_filter) ;
+		return SRC_ERR_MALLOC_FAILED ;
+	}
+	memcpy (to_filter->buffer, from_filter->buffer, sizeof (float) * (from_filter->b_len + from->channels)) ;
 
-	memcpy (to_filter, from_filter, private_length) ;
 	to->private_data = to_filter ;
 
 	return SRC_ERR_NO_ERROR ;
@@ -1150,10 +1161,15 @@
 {
 	if (state)
 	{
-		if (state->private_data)
+		SINC_FILTER *sinc = (SINC_FILTER *) state->private_data ;
+		if (sinc)
 		{
-			free (state->private_data) ;
-			state->private_data = NULL ;
+			if (sinc->buffer)
+			{	free (sinc->buffer) ;
+				sinc->buffer = NULL ;
+				} ;
+			free (sinc) ;
+			sinc = NULL ;
 		}
 	}
 } /* sinc_close */
--- a/src/src_zoh.c
+++ b/src/src_zoh.c
@@ -29,7 +29,7 @@
 	bool	dirty ;
 	long	in_count, in_used ;
 	long	out_count, out_gen ;
-	float	last_value [] ;
+	float	*last_value ;
 } ZOH_DATA ;
 
 /*----------------------------------------------------------------------------------------
@@ -151,7 +151,8 @@
 
 enum SRC_ERR
 zoh_set_converter (SRC_STATE *state, int src_enum)
-{	ZOH_DATA *priv = NULL ;
+{
+	ZOH_DATA *priv = NULL ;
 
 	if (src_enum != SRC_ZERO_ORDER_HOLD)
 		return SRC_ERR_BAD_CONVERTER ;
@@ -159,13 +160,24 @@
 	zoh_close (state) ;
 
 	if (state->private_data == NULL)
-	{	priv = ZERO_ALLOC (ZOH_DATA, sizeof (*priv) + state->channels * sizeof (float)) ;
-		state->private_data = priv ;
-		} ;
+	{
+		priv = ZERO_ALLOC (ZOH_DATA, sizeof (*priv)) ;
+		if (priv)
+		{
+			priv->last_value = calloc (state->channels, sizeof (float)) ;
+			if (!priv->last_value)
+			{
+				free (priv) ;
+				priv = NULL ;
+			}
+		}
+	}
 
 	if (priv == NULL)
 		return SRC_ERR_MALLOC_FAILED ;
 
+	state->private_data = priv ;
+
 	priv->zoh_magic_marker = ZOH_MAGIC_MARKER ;
 
 	state->const_process = zoh_vari_process ;
@@ -191,7 +203,7 @@
 		return ;
 
 	priv->dirty = false ;
-	memset (priv->last_value, 0, sizeof (priv->last_value [0]) * state->channels) ;
+	memset (priv->last_value, 0, sizeof (float) * state->channels) ;
 
 	return ;
 } /* zoh_reset */
@@ -204,12 +216,18 @@
 
 	ZOH_DATA *to_priv = NULL ;
 	ZOH_DATA* from_priv = (ZOH_DATA*) from->private_data ;
-	size_t private_size = sizeof (*to_priv) + from->channels * sizeof (float) ;
 
-	if ((to_priv = ZERO_ALLOC (ZOH_DATA, private_size)) == NULL)
+	if ((to_priv = ZERO_ALLOC (ZOH_DATA, sizeof (ZOH_DATA))) == NULL)
 		return SRC_ERR_MALLOC_FAILED ;
 
-	memcpy (to_priv, from_priv, private_size) ;
+	memcpy (to_priv, from_priv, sizeof (ZOH_DATA)) ;
+	to_priv->last_value = malloc (sizeof (float) * from->channels) ;
+	if (!to_priv->last_value)
+	{	free (to_priv) ;
+		return SRC_ERR_MALLOC_FAILED ;
+		} ;
+	memcpy (to_priv->last_value, from_priv->last_value, sizeof (float) * from->channels) ;
+
 	to->private_data = to_priv ;
 
 	return SRC_ERR_NO_ERROR ;
@@ -220,10 +238,15 @@
 {
 	if (state)
 	{
-		if (state->private_data)
+		ZOH_DATA *zoh = (ZOH_DATA *) state->private_data ;
+		if (zoh)
 		{
-			free (state->private_data) ;
-			state->private_data = NULL ;
+			if (zoh->last_value)
+			{	free (zoh->last_value) ;
+				zoh->last_value = NULL ;
+				} ;
+			free (zoh) ;
+			zoh = NULL ;
 		}
 	}
 } /* zoh_close */