Index: /libmpc/trunk/include/mpc/mpcdec.h
===================================================================
--- /libmpc/trunk/include/mpc/mpcdec.h	(revision 410)
+++ /libmpc/trunk/include/mpc/mpcdec.h	(revision 411)
@@ -62,9 +62,17 @@
 
 typedef struct mpc_frame_info_t {
-	mpc_uint32_t samples;	/// number of samples in the frame (counting once for multiple channels)
-	mpc_int32_t bits;	/// number of bits consumed by this frame (-1) if end of stream
+	mpc_uint32_t samples;		/// number of samples in the frame (counting once for multiple channels)
+	mpc_int32_t bits;			/// number of bits consumed by this frame (-1) if end of stream
 	MPC_SAMPLE_FORMAT * buffer;	/// frame samples buffer (size = samples * channels * sizeof(MPC_SAMPLE_FORMAT))
-	mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer.
+	mpc_bool_t is_key_frame; 	/// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer.
 } mpc_frame_info;
+
+typedef struct mpc_chap_info_t {
+	mpc_uint64_t sample;	/// sample where the chapter starts
+	mpc_uint16_t gain;		/// replaygain chapter value
+	mpc_uint16_t peak;		/// peak chapter loudness level
+	mpc_uint_t tag_size;	/// size of the tag element (0 if no tag is present for this chapter)
+	char * tag;				/// pointer to an APEv2 tag without the preamble
+} mpc_chap_info;
 
 /// Initializes mpc decoder with the supplied stream info parameters.
@@ -128,13 +136,10 @@
 /**
  * Gets datas associated to a given chapter
- * You can pass 0 for tag and tag_size if you don't needs the tag information
  * The chapter tag is an APEv2 tag without the preamble
  * @param d pointer to a musepack demuxer
  * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1)
- * @param tag will return a pointer to the chapter tag datas
- * @param tag_size will be filed with the tag data size (0 if no tag for this chapter)
- * @return the sample where the chapter starts
+ * @return the chapter information structure
  */
-MPC_API mpc_uint64_t mpc_demux_chap(mpc_demux * d, int chap_nb, char ** tag, mpc_uint_t * tag_size);
+MPC_API mpc_chap_info * mpc_demux_chap(mpc_demux * d, int chap_nb);
 
 #ifdef __cplusplus
Index: /libmpc/trunk/libmpcdec/internal.h
===================================================================
--- /libmpc/trunk/libmpcdec/internal.h	(revision 410)
+++ /libmpc/trunk/libmpcdec/internal.h	(revision 411)
@@ -60,10 +60,4 @@
 #define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box
 
-typedef struct {
-	mpc_uint64_t sample; /// sample where the chapter starts
-	mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter)
-	char * tag; /// pointer to an APEv2 tag without the preamble
-} mpc_chap_t;
-
 struct mpc_demux_t {
 	mpc_reader * r;
@@ -86,5 +80,5 @@
 	mpc_seek_t chap_pos; /// supposed position of the first chapter block
 	mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter)
-	mpc_chap_t * chap; /// chapters position and tag
+	mpc_chap_info * chap; /// chapters position and tag
 
 };
Index: /libmpc/trunk/libmpcdec/mpc_demux.c
===================================================================
--- /libmpc/trunk/libmpcdec/mpc_demux.c	(revision 410)
+++ /libmpc/trunk/libmpcdec/mpc_demux.c	(revision 411)
@@ -331,5 +331,5 @@
 		d->chap_nb++;
 		chap_size += size;
-		size = mpc_bits_get_size(&d->bits_reader, &chap_sample);
+		size = mpc_bits_get_size(&d->bits_reader, &chap_sample) + 4;
 		chap_size += size;
 		tag_size += b.size - size;
@@ -340,5 +340,5 @@
 	if (d->chap_nb > 0) {
 		char * ptag;
-		d->chap = malloc(sizeof(mpc_chap_t) * d->chap_nb + tag_size);
+		d->chap = malloc(sizeof(mpc_chap_info) * d->chap_nb + tag_size);
 		ptag = (char*)(d->chap + d->chap_nb);
 
@@ -347,5 +347,7 @@
 		while (memcmp(b.key, "CT", 2) == 0) {
 			mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0);
-			size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample);
+			size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample) + 4;
+			d->chap[i].gain = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16);
+			d->chap[i].peak = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16);
 			memcpy(ptag, d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3), b.size - size);
 			d->bits_reader.buff += b.size - size;
@@ -375,13 +377,10 @@
 /**
  * Gets datas associated to a given chapter
- * You can pass 0 for tag and tag_size if you don't needs the tag information
  * The chapter tag is an APEv2 tag without the preamble
  * @param d pointer to a musepack demuxer
  * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1)
- * @param tag will return a pointer to the chapter tag datas
- * @param tag_size will be filed with the tag data size (0 if no tag for this chapter)
- * @return the sample where the chapter starts
+ * @return the chapter information structure
  */
-mpc_uint64_t mpc_demux_chap(mpc_demux * d, int chap_nb, char ** tag, mpc_uint_t * tag_size)
+mpc_chap_info * mpc_demux_chap(mpc_demux * d, int chap_nb)
 {
 	if (d->chap_nb == -1)
@@ -389,9 +388,5 @@
 	if (chap_nb >= d->chap_nb || chap_nb < 0)
 		return 0;
-	if (tag != 0 && tag_size != 0) {
-		*tag = d->chap[chap_nb].tag;
-		*tag_size = d->chap[chap_nb].tag_size;
-	}
-	return d->chap[chap_nb].sample;
+	return &d->chap[chap_nb];
 }
 
Index: /libmpc/trunk/mpcchap/mpcchap.c
===================================================================
--- /libmpc/trunk/mpcchap/mpcchap.c	(revision 410)
+++ /libmpc/trunk/mpcchap/mpcchap.c	(revision 411)
@@ -30,5 +30,6 @@
 void    Init_Tags        ( void );
 int     FinalizeTags     ( FILE* fp, unsigned int Version, unsigned int flags );
-int     addtag           ( const char* key, size_t keylen, const char* value, size_t valuelen, int converttoutf8, int flags );
+int     addtag           ( const char* key, size_t keylen, const char* value,
+                           size_t valuelen, int converttoutf8, int flags );
 #define TAG_NO_HEADER 1
 #define TAG_NO_FOOTER 2
@@ -39,4 +40,9 @@
 #define atoll _atoi64
 #endif
+
+static const int Ptis[] = {	PTI_TITLE, PTI_PERFORMER, PTI_SONGWRITER, PTI_COMPOSER,
+		PTI_ARRANGER, PTI_MESSAGE, PTI_GENRE};
+static char const * const APE_keys[] = {"Title", "Artist", "Songwriter", "Composer",
+		"Arranger", "Comment", "Genre"};
 
 static void usage(const char *exename)
@@ -77,10 +83,15 @@
 	int nchap = iniparser_getnsec(dict);
 	for (i = 0; i < nchap; i++) {
-		Init_Tags();
-		int j, nitem, tag_len = 0;
+		int j, nitem, ntags = 0, tag_len = 0;
+		mpc_uint16_t gain = 0, peak = 0;
 		char * chap_sec = iniparser_getsecname(dict, i);
 		mpc_int64_t chap_pos = atoll(chap_sec);
+
 		if (chap_pos > si->samples - si->beg_silence)
-			fprintf(stderr, "warning : chapter %i starts @ %lli after the end of the stream (%lli)\n", i + 1, chap_pos, si->samples - si->beg_silence);
+			fprintf(stderr, "warning : chapter %i starts @ %lli samples after the end of the stream (%lli)\n",
+			        i + 1, chap_pos, si->samples - si->beg_silence);
+
+		Init_Tags();
+
 		nitem = iniparser_getnkey(dict, i);
 		for (j = 0; j < nitem; j++) {
@@ -88,16 +99,28 @@
 			int key_len, item_len;
 			item_key = iniparser_getkeyname(dict, i, j, & item_value);
-			key_len = strlen(item_key);
-			item_len = strlen(item_value);
-			addtag(item_key, key_len, item_value, item_len, 0, 0);
-			tag_len += key_len + item_len;
+			if (strcmp(item_key, "gain") == 0)
+				gain = atoi(item_value);
+			else if (strcmp(item_key, "peak") == 0)
+				peak = atoi(item_value);
+			else {
+				key_len = strlen(item_key);
+				item_len = strlen(item_value);
+				addtag(item_key, key_len, item_value, item_len, 0, 0);
+				tag_len += key_len + item_len;
+				ntags++;
+			}
 		}
-		if (nitem > 0) tag_len += 24 + nitem * 9;
+		if (ntags > 0) tag_len += 24 + ntags * 9;
 		char block_header[12] = "CT";
 		char sample_offset[10];
 		int offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE);
-		tag_len = encodeSize(tag_len + offset_size + 2, block_header + 2, MPC_TRUE);
+		tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE);
 		fwrite(block_header, 1, tag_len + 2, in_file);
 		fwrite(sample_offset, 1, offset_size, in_file);
+		sample_offset[0] = gain >> 8;
+		sample_offset[1] = gain & 0xFF;
+		sample_offset[2] = peak >> 8;
+		sample_offset[3] = peak & 0xFF;
+		fwrite(sample_offset, 1, 4, in_file);
 		FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE);
 	}
@@ -115,9 +138,4 @@
 mpc_status add_chaps_cue(char * mpc_file, char * chap_file, mpc_demux * demux, mpc_streaminfo * si)
 {
-	int Ptis[7] = {	PTI_TITLE, PTI_PERFORMER, PTI_SONGWRITER, PTI_COMPOSER,
-			PTI_ARRANGER, PTI_MESSAGE, PTI_GENRE};
-	char * APE_keys[7] = {"Title", "Artist", "Songwriter", "Composer",
-			"Arranger", "Comment", "Genre"};
-
 	Cd *cd = 0;
 	int nchap, format = UNKNOWN;
@@ -155,5 +173,6 @@
 
 		if (chap_pos > si->samples - si->beg_silence)
-			fprintf(stderr, "warning : chapter %i starts @ %lli after the end of the stream (%lli)\n", i, chap_pos, si->samples - si->beg_silence);
+			fprintf(stderr, "warning : chapter %i starts @ %lli samples after the end of the stream (%lli)\n",
+			        i, chap_pos, si->samples - si->beg_silence);
 
 		Init_Tags();
@@ -168,5 +187,5 @@
 
 		for (j = 0; j < (sizeof(Ptis) / sizeof(*Ptis)); j++) {
-			char * item_key = APE_keys[j], * item_value;
+			char const * item_key = APE_keys[j], * item_value;
 			item_value = cdtext_get (Ptis[j], cdtext);
 			if (item_value != 0) {
@@ -183,7 +202,8 @@
 		char sample_offset[10];
 		int offset_size = encodeSize(chap_pos, sample_offset, MPC_FALSE);
-		tag_len = encodeSize(tag_len + offset_size + 2, block_header + 2, MPC_TRUE);
+		tag_len = encodeSize(tag_len + 4 + offset_size + 2, block_header + 2, MPC_TRUE);
 		fwrite(block_header, 1, tag_len + 2, in_file);
 		fwrite(sample_offset, 1, offset_size, in_file);
+		fwrite("\0\0\0\0", 1, 4, in_file); // put unknow chapter gain / peak
 		FinalizeTags(in_file, TAG_VERSION, TAG_NO_FOOTER | TAG_NO_PREAMBLE);
 	}
@@ -201,7 +221,6 @@
 {
 	int i;
-	unsigned int tag_size;
 	FILE * out_file;
-	char * tag;
+	mpc_chap_info * chap;
 
 	if (chap_nb <= 0)
@@ -213,7 +232,9 @@
 
 	for (i = 0; i < chap_nb; i++) {
-		fprintf(out_file, "[%lli]\n", mpc_demux_chap(demux, i, &tag, &tag_size));
-		if (tag_size > 0) {
+		chap = mpc_demux_chap(demux, i);
+		fprintf(out_file, "[%lli]\ngain=%i\npeak=%i\n", chap->sample, chap->gain, chap->peak);
+		if (chap->tag_size > 0) {
 			int item_count, j;
+			char const * tag = chap->tag;
 			item_count = tag[8] | (tag[9] << 8) | (tag[10] << 16) | (tag[11] << 24);
 			tag += 24;
