[xiph-cvs] cvs commit: ices/src mp3.c
Brendan
brendan at xiph.org
Wed Mar 12 04:12:58 PST 2003
brendan 03/03/12 07:12:58
Modified: src mp3.c
Log:
Cleanup (real fix for memory-clobbering bug noted yesterday in stream.c).
It's a medium-sized shuffle, I hope I didn't break anything.
Caught another edge case.
Revision Changes Path
1.22 +44 -41 ices/src/mp3.c
Index: mp3.c
===================================================================
RCS file: /cvs/ice/ices/src/mp3.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- mp3.c 11 Mar 2003 22:28:53 -0000 1.21
+++ mp3.c 12 Mar 2003 12:12:58 -0000 1.22
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * $Id: mp3.c,v 1.21 2003/03/11 22:28:53 brendan Exp $
+ * $Id: mp3.c,v 1.22 2003/03/12 12:12:58 brendan Exp $
*/
#include "definitions.h"
@@ -98,11 +98,11 @@
ices_mp3_in_t* mp3_data = (ices_mp3_in_t*) source->data;
unsigned char *buffer;
mp3_header_t mh;
- size_t len, rlen;
- int rc = 1;
+ size_t len;
+ int rc = 0;
int off = 0;
- if (! mp3_data->len)
+ if (mp3_data->len < 4)
return 1;
/* Ogg/Vorbis often contains bits that almost look like MP3 headers */
@@ -110,45 +110,47 @@
return 1;
/* first check for ID3v2 */
- if (! strncmp ("ID3", mp3_data->buf, 3)) {
+ if (! strncmp ("ID3", mp3_data->buf, 3))
ices_id3v2_parse (source);
- /* We're committed now. If we don't find an MP3 header the file is
- * garbage */
- rc = -1;
+
+ /* refill buffer if ID3v2 parsing consumed it */
+ if (!mp3_data->len) {
+ buffer = (unsigned char*) malloc (MP3_BUFFER_SIZE);
+ len = source->read (source, buffer, MP3_BUFFER_SIZE);
+ mp3_data->buf = buffer;
+ mp3_data->len = len;
+ mp3_data->pos = 0;
+ }
+
+ if (mp3_data->len < 4) {
+ ices_log_error("Short file");
+ return -1;
}
/* seek past garbage if necessary */
+ buffer = mp3_data->buf;
do {
- len = mp3_data->len;
- buffer = mp3_data->buf;
+ len = mp3_data->len - mp3_data->pos;
- if (!len) {
- buffer = (unsigned char*) malloc (MP3_BUFFER_SIZE);
- len = source->read (source, buffer, MP3_BUFFER_SIZE);
+ /* copy remaining bytes to front, refill buffer without malloc/free */
+ if (len < 4) {
+ memcpy (buffer, buffer + mp3_data->pos, len);
+ /* make read fetch from source instead of buffer */
+ mp3_data->buf = NULL;
+ len += source->read(source, buffer + len, mp3_data->len - len);
mp3_data->buf = buffer;
- mp3_data->len = len;
mp3_data->pos = 0;
+ if (len < 4)
+ break;
}
- /* we must be able to read at least 4 bytes of header */
- while (!(rc = mp3_parse_frame(buffer + mp3_data->pos, &mh)) && (mp3_data->len >= 4)) {
+ /* we must be able to read at least 4 bytes of header */
+ while (mp3_data->len - mp3_data->pos >= 4
+ && !(rc = mp3_parse_frame(buffer + mp3_data->pos, &mh))) {
mp3_data->pos++;
- mp3_data->len--;
off++;
}
-
- len = mp3_data->len;
- /* copy remaining bits to front, refill buffer without malloc/free */
- if (len && len < 4) {
- memcpy (buffer, buffer + mp3_data->pos, len);
- /* make read fetch from source instead of buffer */
- mp3_data->len = 0;
- rlen = source->read(source, buffer + len, MP3_BUFFER_SIZE - len);
- mp3_data->len = len + rlen;
- mp3_data->pos = 0;
- len = rlen;
- }
- } while (!rc && len);
+ } while (!rc);
if (!rc) {
ices_log_error ("Couldn't find synch");
@@ -161,6 +163,7 @@
source->samplerate = mh.samplerate;
source->bitrate = mh.bitrate;
+ /* bitrate of zero ensures that lazy reencoding won't be lazy */
if (mp3_check_vbr(source, &mh) > 0)
source->bitrate = 0;
@@ -225,19 +228,18 @@
ices_mp3_read (input_stream_t* self, void* buf, size_t len)
{
ices_mp3_in_t* mp3_data = self->data;
+ int remaining;
int rlen = 0;
- if (mp3_data->len) {
- if (mp3_data->len > len) {
+ if (mp3_data->buf) {
+ remaining = mp3_data->len - mp3_data->pos;
+ if (remaining > len) {
rlen = len;
memcpy (buf, mp3_data->buf + mp3_data->pos, len);
- mp3_data->len -= len;
mp3_data->pos += len;
} else {
- rlen = mp3_data->len;
- memcpy (buf, mp3_data->buf + mp3_data->pos, mp3_data->len);
- mp3_data->len = 0;
- mp3_data->pos = 0;
+ rlen = remaining;
+ memcpy (buf, mp3_data->buf + mp3_data->pos, remaining);
free (mp3_data->buf);
mp3_data->buf = NULL;
}
@@ -259,7 +261,7 @@
ices_mp3_readpcm (input_stream_t* self, size_t len, int16_t* left,
int16_t* right)
{
- unsigned char buf[4096];
+ unsigned char buf[MP3_BUFFER_SIZE];
ssize_t rlen;
int nsamples = 0;
@@ -338,14 +340,15 @@
mp3_header_t next_header;
ssize_t framelen;
off_t cur;
+ int offset;
if (!source->canseek)
return -1;
cur = lseek(source->fd, 0, SEEK_CUR);
-
+ offset = mp3_data->len - mp3_data->pos;
/* check for Xing VBR tag */
- lseek(source->fd, 36 - (ssize_t)mp3_data->len, SEEK_CUR);
+ lseek(source->fd, 36 - offset, SEEK_CUR);
if (read(source->fd, buf, 4) == 4) {
if (!strncmp("Xing", buf, 4)) {
ices_log_debug("VBR tag found");
@@ -362,7 +365,7 @@
lseek(source->fd, cur, SEEK_SET);
if ((framelen = mp3_frame_length(header))) {
ices_log_debug("Frame length expected: %d bytes", framelen);
- lseek(source->fd, framelen - (ssize_t)mp3_data->len, SEEK_CUR);
+ lseek(source->fd, framelen - offset, SEEK_CUR);
if (read(source->fd, buf, 4) == 4) {
if (!mp3_parse_frame(buf, &next_header))
ices_log_debug("Couldn't find second frame header");
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list