Index: libmpcdec/branches/zorg/src/streaminfo.c
===================================================================
--- libmpcdec/branches/zorg/src/streaminfo.c	(revision 81)
+++ libmpcdec/branches/zorg/src/streaminfo.c	(revision 104)
@@ -35,7 +35,11 @@
 /// Implementation of streaminfo reading functions.
 
+#include <mpcdec/mpcdec.h>
 #include <mpcdec/streaminfo.h>
 #include <stdio.h>
 #include "internal.h"
+
+mpc_uint32_t mpc_bits_read(mpc_bits_reader * r, const unsigned int nb_bits);
+unsigned int mpc_bits_get_size(mpc_bits_reader * r, mpc_uint64_t * p_size);
 
 static const char na[] = "n.a.";
@@ -53,54 +57,63 @@
 }
 
+static void
+mpc_get_encoder_string(mpc_streaminfo* si)
+{
+	if (si->encoder_version == 0) {
+		sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
+	} else {
+		switch (si->encoder_version % 10) {
+			case 0:
+				sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100,
+						si->encoder_version / 10 % 10);
+				break;
+			case 2: case 4: case 6: case 8:
+				sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100,
+						si->encoder_version % 100);
+				break;
+			default:
+				sprintf(si->encoder, "--Alpha-- %u.%02u",
+						si->encoder_version / 100, si->encoder_version % 100);
+				break;
+		}
+	}
+}
+
 /// Reads streaminfo from SV7 header.
-static mpc_status
-streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_uint32_t HeaderData[8])
+mpc_status
+streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r)
 {
     mpc_uint16_t Estimatedpeak_title = 0;
 
-    if (si->stream_version > 0x71) {
-        //        Update (si->stream_version);
-        return MPC_STATUS_OK;
-    }
-
-    si->bitrate            = 0;
-    si->frames             = HeaderData[1];
-    si->is                 = 0;
-    si->ms                 = (HeaderData[2] >> 30) & 0x0001;
-    si->max_band           = (HeaderData[2] >> 24) & 0x003F;
-    si->block_size         = 1;
-    si->profile            = (HeaderData[2] << 8) >> 28;
+	si->bitrate            = 0;
+	si->block_size         = 1;
+	si->frames             = mpc_bits_read(r, 32);
+	si->is                 = mpc_bits_read(r, 1); // should be 0
+	si->ms                 = mpc_bits_read(r, 1);
+	si->max_band           = mpc_bits_read(r, 6);
+	si->profile            = mpc_bits_read(r, 4);
     si->profile_name       = mpc_get_version_string(si->profile);
-    si->sample_freq        = samplefreqs[(HeaderData[2] >> 16) & 0x0003];
-    Estimatedpeak_title    = (mpc_uint16_t) (HeaderData[2] & 0xFFFF);   // read the ReplayGain data
-    si->gain_title         = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF);
-    si->peak_title         = (mpc_uint16_t) (HeaderData[3] & 0xFFFF);
-    si->gain_album         = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF);
-    si->peak_album         = (mpc_uint16_t) (HeaderData[4] & 0xFFFF);
-    si->is_true_gapless    = (HeaderData[5] >> 31) & 0x0001; // true gapless: used?
-    si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF; // true gapless: valid samples for last frame
-    si->fast_seek          = (HeaderData[5] >> 19) & 0x0001; // fast seeking
-    si->encoder_version    = (HeaderData[6] >> 24) & 0x00FF;
+	mpc_bits_read(r, 2); // Link ?
+	si->sample_freq        = samplefreqs[mpc_bits_read(r, 2)];
+	Estimatedpeak_title    = (mpc_uint16_t) mpc_bits_read(r, 16);   // read the ReplayGain data
+	si->gain_title         = (mpc_uint16_t) mpc_bits_read(r, 16);
+	si->peak_title         = (mpc_uint16_t) mpc_bits_read(r, 16);
+	si->gain_album         = (mpc_uint16_t) mpc_bits_read(r, 16);
+	si->peak_album         = (mpc_uint16_t) mpc_bits_read(r, 16);
+	si->is_true_gapless    = mpc_bits_read(r, 1); // true gapless: used?
+	si->last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame
+	si->fast_seek          = mpc_bits_read(r, 1); // fast seeking
+	mpc_bits_read(r, 19); // unused
+	si->encoder_version    = mpc_bits_read(r, 8);
     si->channels           = 2;
 
-    if (si->encoder_version == 0) {
-        sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
-    }
-    else {
-        switch (si->encoder_version % 10) {
-        case 0:
-            sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100,
-                    si->encoder_version / 10 % 10);
-            break;
-        case 2: case 4: case 6: case 8:
-            sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100,
-                    si->encoder_version % 100);
-            break;
-        default:
-            sprintf(si->encoder, "--Alpha-- %u.%02u",
-                    si->encoder_version / 100, si->encoder_version % 100);
-            break;
-        }
-    }
+	mpc_get_encoder_string(si);
+
+	// estimation, exact value needs too much time
+	si->pcm_samples     = 1152 * si->frames - 576;
+	si->average_bitrate = 0;
+	if (si->pcm_samples > 0)
+		si->average_bitrate = (si->tag_offset  - si->header_position) * 8.0
+				*  si->sample_freq / si->pcm_samples;
 
     return MPC_STATUS_OK;
@@ -108,39 +121,24 @@
 
 /// Reads streaminfo from SV8 header.
-static mpc_status
-streaminfo_read_header_sv8(mpc_streaminfo* si, mpc_reader * p_reader)
+mpc_status
+streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in)
 {
-	int ret;
-	mpc_block_t block;
-	mpc_bits_reader bits_reader = {0, 0};
 	mpc_uint32_t CRC;
-	mpc_int32_t header_pos;
-	unsigned char tmp;
 	mpc_uint64_t sampleCount = 0;
-
-	ret = mpc_find_block(p_reader, &block, "SI", "AD");
-	if (ret != MPC_STATUS_OK)
-		return ret;
-
-	header_pos = p_reader->tell(p_reader);
+	mpc_bits_reader r = *r_in;
 
 	// FIXME : add CRC check
-	CRC = mpc_read_bits(p_reader, &bits_reader, 32);
-	si->stream_version = mpc_read_bits(p_reader, &bits_reader, 8);
-
-	do {
-		p_reader->read(p_reader, &tmp, 1);
-		sampleCount = (sampleCount << 7) | (tmp & 0x7F);
-	} while((tmp & 0x80));
-
+	CRC = mpc_bits_read(&r, 32);
+	si->stream_version = mpc_bits_read(&r, 8);
+	mpc_bits_get_size(&r, &sampleCount);
 	si->frames = (sampleCount + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH;
 	si->is_true_gapless = 1;
 	si->last_frame_samples = sampleCount - (si->frames - 1) * MPC_FRAME_LENGTH;
-	si->sample_freq = samplefreqs[mpc_read_bits(p_reader, &bits_reader, 4)];
-	si->channels = mpc_read_bits(p_reader, &bits_reader, 4) + 1;
-	si->max_band = mpc_read_bits(p_reader, &bits_reader, 5) + 1;
+	si->sample_freq = samplefreqs[mpc_bits_read(&r, 4)];
+	si->channels = mpc_bits_read(&r, 4) + 1;
+	si->max_band = mpc_bits_read(&r, 5) + 1;
 	// FIXME : this flag will be removed, must be 0
-	si->is = mpc_read_bits(p_reader, &bits_reader, 1);
-	si->ms = mpc_read_bits(p_reader, &bits_reader, 1);
+	si->is = mpc_bits_read(&r, 1);
+	si->ms = mpc_bits_read(&r, 1);
 
 	si->bitrate            = 0;
@@ -152,69 +150,4 @@
 		si->average_bitrate = (si->tag_offset - si->header_position) * 8.0
 				*  si->sample_freq / si->pcm_samples;
-
-	// seek to the end of the block
-	p_reader->seek(p_reader, header_pos + block.size);
-
-	return MPC_STATUS_OK;
-}
-
-// reads file header and tags
-mpc_status
-mpc_streaminfo_init(mpc_streaminfo * si, mpc_reader *p_reader)
-{
-    mpc_uint32_t headerData[8]; int err;
-
-    memset(si, 0, sizeof *si);
-    // get header position
-    err = si->header_position = mpc_skip_id3v2(p_reader);
-    if(err < 0) return MPC_STATUS_FILE;
-
-    // seek to first byte of mpc data
-    err = p_reader->seek(p_reader, si->header_position);
-    if(!err) return MPC_STATUS_FILE;
-
-	// read magic
-	err = p_reader->read(p_reader, headerData, 4);
-	if(err != 4) return MPC_STATUS_FILE;
-
-	if (memcmp(headerData, "MP+", 3) == 0) {
-		// SV 4-7
-		err = p_reader->read(p_reader, headerData + 1, 7 * 4);
-		if(err != 7 * 4) return MPC_STATUS_FILE;
-		err = p_reader->seek(p_reader, si->header_position + 6 * 4);
-		if(!err) return MPC_STATUS_FILE;
-
-		err = p_reader->get_size(p_reader);
-		if(err < 0) return MPC_STATUS_FILE;
-		si->tag_offset = si->total_file_length = err;
-
-#ifndef MPC_LITTLE_ENDIAN
-		{
-			mpc_uint32_t ptr;
-			for (ptr = 0; ptr < 8; ptr++)
-				headerData[ptr] = mpc_swap32(headerData[ptr]);
-		}
-#endif
-		si->stream_version = headerData[0] >> 24;
-
-		if ((si->stream_version & 15) >= 8)
-			return MPC_STATUS_INVALIDSV;
-		else if ((si->stream_version & 15) == 7) {
-			err = streaminfo_read_header_sv7(si, headerData);
-			if(err < 0) return err;
-		}
-
-		// estimation, exact value needs too much time
-		si->pcm_samples     = 1152 * si->frames - 576;
-		si->average_bitrate = 0;
-		if (si->pcm_samples > 0)
-			si->average_bitrate = (si->tag_offset  - si->header_position) * 8.0
-					*  si->sample_freq / si->pcm_samples;
-	} else if (memcmp(headerData, "MPCK", 4) == 0) {
-		// SV 8
-		printf("sv8\n");
-		streaminfo_read_header_sv8(si, p_reader);
-	} else
-		return MPC_STATUS_INVALIDSV;
 
 	return MPC_STATUS_OK;
