[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[pygame] Bug in sndarray.c
- To: "Pygame Mailing List" <pygame-users@xxxxxxxx>
- Subject: [pygame] Bug in sndarray.c
- From: "Eyal Lotem" <eyal.lotem@xxxxxxxxx>
- Date: Thu, 28 Aug 2008 06:03:39 +0300
- Delivered-to: archiver@xxxxxxxx
- Delivered-to: pygame-users-outgoing@xxxxxxxx
- Delivered-to: pygame-users@xxxxxxxx
- Delivery-date: Wed, 27 Aug 2008 23:03:45 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:mime-version:content-type; bh=upl5mp3zZ4hegdYSeB6DAcsmQly//opMQgSYy4dwi/U=; b=i4GDhhPO1qIHx1bEnOqUkeq3MLUPD+NHXwyyNe+3u4Kq3EiOSvNtPc0Koay7p42Etc QpNs74/uEjwhbFEQcjfoeRxkDE9RE+79vaL2/KJyNHRvpharhsnhNQIjtTnCBadmAzbV Nf7ZE/wBihHi2raL9ZoeVQR+2xUXFba7L++UE=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type; b=HoCl0UXIO1USOh1Ibn5tjzPaSzNHNyVspNORxL/hM2mHBdNZDAURWDzZrTaj2wLvii UAhqo+/mdgrMRGZSGXdzw3+0jt32r3ouy/noTVYzXsurzEGVssBN2C0OeZBQw+jHl8f/ /38m1CyKj+oCqltkdaqnyNiA5if7akcIhWKrQ=
- Reply-to: pygame-users@xxxxxxxx
- Sender: owner-pygame-users@xxxxxxxx
(Please CC me for all correspondence, thanks)
In pygame 1.7.1release-4.1ubuntu1 (Ubuntu Hardy's version), there is a
bug where 64-bit machines cannot use sndarray_make_sound, as the data
isn't copied, and instead garbage is inserted to the result sound
object.
The function sndarray.c: sndarray_make_sound assumes that the given
arrays' elements sizes will be 1, 2 or 4. It also unnecessarily casts
the pointers both before and after dereferences. This unnecessarily
differentiated between otherwise identical handling of the differing
sizes, which causes the need for the cases in the first place.
Perhaps the reason behind the cases was allowing compiler
optimization, but apparently it is too risky (bug-wise).
The "cheap" way out would be to add the case for size=8, but that
would break too upon other word-sized machines. If this cheap
solution is chosen, its probably a good idea to add a "default" case
which errorizes. Also, this isn't very optimal, as the switch-case
can be put out of the heavier loop over all the samples (it is
re-checked for every sample, so its not very optimized anyhow!).
The simplifying/fixing patch is attached.
--- pygame-1.7.1release/src/sndarray.c 2004-06-20 07:58:05.000000000 +0300
+++ pygame-1.7.1release/src/sndarray.c.fixed 2008-08-28 05:57:54.000000000 +0300
@@ -191,21 +191,8 @@
for(loop1=0; loop1<length; loop1++)
{
src = (Uint8*)array->data + loop1*step1;
- switch(array->descr->elsize)
- {
- case 1:
- for(loop2=0; loop2<length2; loop2++, dst+=1, src+=step2)
- *(Uint8*)dst = (Uint8)*((Uint8*)src);
- break;
- case 2:
- for(loop2=0; loop2<length2; loop2++, dst+=1, src+=step2)
- *(Uint8*)dst = (Uint8)*((Uint16*)src);
- break;
- case 4:
- for(loop2=0; loop2<length2; loop2++, dst+=1, src+=step2)
- *(Uint8*)dst = (Uint8)*((Uint32*)src);
- break;
- }
+ for(loop2=0; loop2<length2; loop2++, dst+=1, src+=step2)
+ *(Uint8*)dst = *(Uint8*)src;
}
}
else
@@ -213,19 +200,15 @@
for(loop1 = 0; loop1 < length; loop1++)
{
src = (Uint8*)array->data + loop1*step1;
- switch(array->descr->elsize)
+ switch(step2)
{
case 1:
for(loop2=0; loop2<length2; loop2++, dst+=2, src+=step2)
- *(Uint16*)dst = (Uint16)(*((Uint8*)src)<<8);
- break;
- case 2:
- for(loop2=0; loop2<length2; loop2++, dst+=2, src+=step2)
- *(Uint16*)dst = (Uint16)*((Uint16*)src);
+ *(Uint16*)dst = (*((Uint8*)src)<<8);
break;
- case 4:
+ default:
for(loop2=0; loop2<length2; loop2++, dst+=2, src+=step2)
- *(Uint16*)dst = (Uint16)*((Uint32*)src);
+ *(Uint16*)dst = *(Uint16*)src;
break;
}
}