Index: mppenc/branches/r2d/libmpcenc/bitstream.c
===================================================================
--- mppenc/branches/r2d/libmpcenc/bitstream.c	(revision 71)
+++ mppenc/branches/r2d/libmpcenc/bitstream.c	(revision 78)
@@ -23,162 +23,100 @@
 #include "stdio.h"
 
+unsigned long crc32(unsigned char *buf, int len);
 
-/*
- *  Change_Endian32() changes the endianess of a 32-bit memory block in-place
- *  by swapping the byte order. This is a little bit tricky, but a well
- *  known method which is much much faster, especially on modern CPUs, than
- *  byte picking, because it avoids memory aliasing. Note that this method
- *  is poison for old 16-bit compilers!
- */
-
-#if ENDIAN == HAVE_BIG_ENDIAN
-
-static void
-Change_Endian32 ( unsigned int* dst, mpc_size_t words32bit )
+void emptyBits(mpc_encoder_t * e)
 {
-    for ( ; words32bit--; dst++ ) {
-# if  INT_MAX >= 2147483647L
-        unsigned int  tmp = *dst;
-        tmp  = ((tmp << 0x10) & 0xFFFF0000) | ((tmp >> 0x10) & 0x0000FFFF);
-        tmp  = ((tmp << 0x08) & 0xFF00FF00) | ((tmp >> 0x08) & 0x00FF00FF);
-        *dst = tmp;
-# else
-        char  tmp;
-        tmp             = ((char*)dst)[0];
-        ((char*)dst)[0] = ((char*)dst)[3];
-        ((char*)dst)[3] = tmp;
-        tmp             = ((char*)dst)[1];
-        ((char*)dst)[1] = ((char*)dst)[2];
-        ((char*)dst)[2] = tmp;
-# endif
-    }
-    return;
+	while( e->bitsCount >= 8 ){
+		e->bitsCount -= 8;
+		e->buffer[e->pos] = (mpc_uint8_t) (e->bitsBuff >> e->bitsCount);
+		e->pos++;
+	}
 }
 
-#endif /* ENDIAN == HAVE_BIG_ENDIAN */
+void writeBits (mpc_encoder_t * e, mpc_uint32_t input, unsigned int bits )
+{
+	e->outputBits += bits;
+
+	if (e->bitsCount + bits > sizeof(e->bitsBuff) * 8) {
+		int tmp = (sizeof(e->bitsBuff) * 8 - e->bitsCount);
+		bits -= tmp;
+		e->bitsBuff = (e->bitsBuff << tmp) | (input >> bits);
+		e->bitsCount = sizeof(e->bitsBuff) * 8;
+		emptyBits(e);
+		input &= (1 << bits) - 1;
+	}
+	e->bitsBuff = (e->bitsBuff << bits) | input;
+	e->bitsCount += bits;
+}
+
+unsigned int encodeSize(mpc_uint64_t size, char * buff, mpc_bool_t addCodeSize)
+{
+	unsigned int i = 1;
+	int j;
+
+	if (addCodeSize) {
+		while ((1 << (7 * i)) - i <= size) i++;
+		size += i;
+	} else
+		while ((1 << (7 * i)) <= size) i++;
+
+	for( j = i - 1; j >= 0; j--){
+		buff[j] = (char) (size | 0x80);
+		size >>= 7;
+	}
+	buff[i - 1] &= 0x7F;
+
+	return i;
+}
+
+void writeMagic(mpc_encoder_t * e)
+{
+	fwrite("MPCK", sizeof(char), 4, e->outputFile);
+	e->outputBits += 32;
+	e->framesInBlock = 0;
+}
+
+void writeBlock ( mpc_encoder_t * e, const char * key, const mpc_bool_t addCRC)
+{
+	FILE * fp = e->outputFile;
+	mpc_uint32_t written = 0;
+	mpc_uint8_t * datas = e->buffer;
+	char blockSize[10];
+	mpc_uint_t len;
+
+	writeBits(e, 0, (8 - e->bitsCount) % 8);
+	emptyBits(e);
+
+	// write block header (key / length)
+	len = encodeSize(e->pos + 2, blockSize, TRUE);
+	fwrite(key, sizeof(char), 2, fp);
+	fwrite(blockSize, sizeof(char), len, fp);
+	e->outputBits += (len + 2) * 8;
 
 
-void
-FlushBitstream ( FILE* fp, const mpc_uint32_t* buffer, mpc_size_t words32bit )
-{
-    mpc_size_t           WrittenDwords = 0;
-    const mpc_uint32_t*  p             = buffer;
-#if ENDIAN == HAVE_BIG_ENDIAN
-    mpc_size_t           CC            = words32bit;
-#endif
+	if (addCRC) {
+		char tmp[4];
+		unsigned long CRC32 = crc32((unsigned char *) e->buffer, e->pos);
+		tmp[0] = (char) (CRC32 >> 24);
+		tmp[1] = (char) (CRC32 >> 16);
+		tmp[2] = (char) (CRC32 >> 8);
+		tmp[3] = (char) CRC32;
+		fwrite(tmp, sizeof(char), 4, fp);
+		e->outputBits += 32;
+	}
 
-#if ENDIAN == HAVE_BIG_ENDIAN
-    Change_Endian32 ( (mpc_uint32_t*)buffer, CC );
-#endif
-
-    // Write e->Buffer
-    do {
-        WrittenDwords = fwrite ( p, sizeof(*buffer), words32bit, fp );
-        if ( WrittenDwords == 0 ) {
-			// FIXME : move stderr_printf to common
-//             stderr_printf ( "\b\n WARNING: Disk full?, retry after 10 sec ...\a" );
+	// write datas
+	while ( e->pos != 0 ) {
+		written = fwrite ( datas, sizeof(*e->buffer), e->pos, fp );
+		if ( written == 0 ) {
 			sprintf(stderr, "\b\n WARNING: Disk full?, retry after 10 sec ...\a");
             sleep (10);
         }
-        if ( WrittenDwords > 0 ) {
-            p          += WrittenDwords;
-            words32bit -= WrittenDwords;
+		if ( written > 0 ) {
+			datas += written;
+			e->pos -= written;
         }
-    } while ( words32bit != 0 );
-
-#if ENDIAN == HAVE_BIG_ENDIAN
-    Change_Endian32 ( (mpc_uint32_t*)buffer, CC );
-#endif
-}
-
-
-void
-UpdateHeader ( FILE* fp, mpc_uint32_t Frames, mpc_uint_t ValidSamples )
-{
-    mpc_uint8_t  buff [4];
-
-    // Write framecount to header
-    if ( fseek ( fp, 4L, SEEK_SET ) < 0 )
-        return;
-
-    buff [0] = (mpc_uint8_t)(Frames >>  0);
-    buff [1] = (mpc_uint8_t)(Frames >>  8);
-    buff [2] = (mpc_uint8_t)(Frames >> 16);
-    buff [3] = (mpc_uint8_t)(Frames >> 24);
-
-    fwrite ( buff, 1, 4, fp );
-
-    // Write ValidSamples to header
-    if ( fseek ( fp, 22L, SEEK_SET ) < 0 )
-        return;
-    fread ( buff, 1, 2, fp );
-    if ( ferror(fp) )
-        return;
-    if ( fseek ( fp, 22L, SEEK_SET ) < 0 )
-        return;
-
-    ValidSamples <<= 4;
-    ValidSamples  |= 0x800F & (((mpc_uint_t) buff[1] << 8) | buff[0]);
-    buff [0] = (mpc_uint8_t)(ValidSamples >>  0);
-    buff [1] = (mpc_uint8_t)(ValidSamples >>  8);
-
-    fwrite ( buff, 1, 2, fp );
-
-
-    // Set filepointer to end of file (dirty method, should be old position!!)
-    fseek ( fp, 0L, SEEK_END );
-}
-
-
-void WriteBits (mpc_encoder_t * e, const mpc_uint32_t input, const unsigned int bits )
-{
-    e->BufferedBits += bits;
-    e->filled       -= bits;
-
-    if      ( e->filled > 0 ) {
-        e->dword  |= input << e->filled;
-    }
-    else if ( e->filled < 0 ) {
-        e->Buffer [e->Zaehler++] = e->dword | ( input >> -e->filled );
-        e->filled += 32;
-        e->dword   = input << e->filled;
-    }
-    else {
-        e->Buffer [e->Zaehler++] = e->dword | input;
-        e->filled  = 32;
-        e->dword   =  0;
-    }
-}
-
-// Bits in the original stream have to be 0, maximum X bits allowed to be set in input
-// Actual bitstream must have already written ptr[0] and ptr[1]
-void WriteBitsAt (mpc_encoder_t * e, const mpc_uint32_t input, const unsigned int bits, BitstreamPos const pos )
-{
-    mpc_uint32_t*     ptr    = pos.ptr;
-    int           filled = pos.bit - bits;
-
-//    fprintf ( stderr, "%5u %2u %08lX %2u\n", input, bits, pos.ptr, pos.bit );
-
-    e->Buffer [e->Zaehler] = e->dword;
-
-    if      ( filled > 0 ) {
-        ptr [0] |= input << (  +filled);
-    }
-    else if ( filled < 0 ) {
-        ptr [0] |= input >> (  -filled);
-        ptr [1] |= input << (32+filled);
-    }
-    else {
-        ptr [0] |= input;
-    }
-
-    e->dword = e->Buffer [e->Zaehler];
-}
-
-
-void GetBitstreamPos (mpc_encoder_t * e, BitstreamPos* const pos )
-{
-    pos -> ptr = e->Buffer + e->Zaehler;
-    pos -> bit = e->filled;
+	}
+	e->framesInBlock = 0;
 }
 
