[Python-checkins] CVS: python/dist/src/Modules audioop.c,1.46,1.47

Tim Peters tim_one@users.sourceforge.net
2001年12月06日 16:37:41 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv21115/python/Modules
Modified Files:
	audioop.c 
Log Message:
audioop_ratecv() again: settle for a sloppier upper bound that's less
obnoxious to compute and easier to explain. No compromise on safety.
Index: audioop.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/audioop.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -d -r1.46 -r1.47
*** audioop.c	2001年12月05日 22:30:21	1.46
--- audioop.c	2001年12月07日 00:37:39	1.47
***************
*** 3,7 ****
 
 #include "Python.h"
- #include <math.h>
 
 #if SIZEOF_INT == 4
--- 3,6 ----
***************
*** 982,1025 ****
 		 ceiling(len*outrate/inrate) output frames, and each frame
 		 requires bytes_per_frame bytes. Computing this
! 		 without spurious overflow is the challenge. */
! 		int ceiling; /* the number of output frames, eventually */
 		int nbytes; /* the number of output bytes needed */
 		int q = len / inrate;
! 		int r = len - q * inrate;
! 		/* Now len = q * inrate + r exactly, so
! 		 len*outrate/inrate =
! 		 (q*inrate+r)*outrate/inrate =
! 		 (q*inrate*outrate + r*outrate)/inrate =
! 		 q*outrate + r*outrate/inrate exactly.
! 		 q*outrate is an exact integer, so the ceiling we're after is
! 		 q*outrate + ceiling(r*outrate/inrate). */
! 		ceiling = q * outrate;
! 		if (ceiling / outrate != q) {
! 			PyErr_SetString(PyExc_MemoryError,
! 				"not enough memory for output buffer");
! 			goto exit;
! 		}
! 		/* Since r = len % inrate, in particular r < inrate. So
! 		 r * outrate / inrate = (r / inrate) * outrate < outrate,
! 		 so ceiling(r * outrate / inrate) <= outrate: the final
! 		 result fits in an int -- it can't overflow. */
! 		assert(r < inrate);
! 		q = (int)ceil((double)r * (double)outrate / (double)inrate);
! 		assert(q <= outrate);
! 		ceiling += q;
! 		if (ceiling < 0) {
! 			PyErr_SetString(PyExc_MemoryError,
! 				"not enough memory for output buffer");
! 			goto exit;
! 		}
 		nbytes = ceiling * bytes_per_frame;
! 		if (nbytes / bytes_per_frame != ceiling) {
 			PyErr_SetString(PyExc_MemoryError,
 				"not enough memory for output buffer");
 			goto exit;
 		}
- 		str = PyString_FromStringAndSize(NULL, nbytes);
- 		if (str == NULL)
- 			goto exit;
 	}
 	ncp = PyString_AsString(str);
--- 981,1010 ----
 		 ceiling(len*outrate/inrate) output frames, and each frame
 		 requires bytes_per_frame bytes. Computing this
! 		 without spurious overflow is the challenge; we can
! 		 settle for a reasonable upper bound, though. */
! 		int ceiling; /* the number of output frames */
 		int nbytes; /* the number of output bytes needed */
 		int q = len / inrate;
! 		/* Now len = q * inrate + r exactly (with r = len % inrate),
! 		 and this is less than q * inrate + inrate = (q+1)*inrate.
! 		 So a reasonable upper bound on len*outrate/inrate is
! 		 ((q+1)*inrate)*outrate/inrate =
! 		 (q+1)*outrate.
! 		*/
! 		ceiling = (q+1) * outrate;
 		nbytes = ceiling * bytes_per_frame;
! 		/* See whether anything overflowed; if not, get the space. */
! 		if (q+1 < 0 ||
! 		 ceiling / outrate != q+1 ||
! 		 nbytes / bytes_per_frame != ceiling)
! 			str = NULL;
! 		else
! 			str = PyString_FromStringAndSize(NULL, nbytes);
! 
! 		if (str == NULL) {
 			PyErr_SetString(PyExc_MemoryError,
 				"not enough memory for output buffer");
 			goto exit;
 		}
 	}
 	ncp = PyString_AsString(str);

AltStyle によって変換されたページ (->オリジナル) /