Ignore:
Timestamp:
10/27/06 18:42:05 (18 years ago)
Author:
r2d
Message:
  • added crc32
  • first sv8 encodes, main changes in bitstream.c
File:
1 edited

Legend:

Unmodified
Added
Removed
  • mppenc/branches/r2d/libmpcenc/bitstream.c

    r71 r78  
    2323#include "stdio.h"
    2424
     25unsigned long crc32(unsigned char *buf, int len);
    2526
    26 /*
    27  *  Change_Endian32() changes the endianess of a 32-bit memory block in-place
    28  *  by swapping the byte order. This is a little bit tricky, but a well
    29  *  known method which is much much faster, especially on modern CPUs, than
    30  *  byte picking, because it avoids memory aliasing. Note that this method
    31  *  is poison for old 16-bit compilers!
    32  */
    33 
    34 #if ENDIAN == HAVE_BIG_ENDIAN
    35 
    36 static void
    37 Change_Endian32 ( unsigned int* dst, mpc_size_t words32bit )
     27void emptyBits(mpc_encoder_t * e)
    3828{
    39     for ( ; words32bit--; dst++ ) {
    40 # if  INT_MAX >= 2147483647L
    41         unsigned int  tmp = *dst;
    42         tmp  = ((tmp << 0x10) & 0xFFFF0000) | ((tmp >> 0x10) & 0x0000FFFF);
    43         tmp  = ((tmp << 0x08) & 0xFF00FF00) | ((tmp >> 0x08) & 0x00FF00FF);
    44         *dst = tmp;
    45 # else
    46         char  tmp;
    47         tmp             = ((char*)dst)[0];
    48         ((char*)dst)[0] = ((char*)dst)[3];
    49         ((char*)dst)[3] = tmp;
    50         tmp             = ((char*)dst)[1];
    51         ((char*)dst)[1] = ((char*)dst)[2];
    52         ((char*)dst)[2] = tmp;
    53 # endif
    54     }
    55     return;
     29        while( e->bitsCount >= 8 ){
     30                e->bitsCount -= 8;
     31                e->buffer[e->pos] = (mpc_uint8_t) (e->bitsBuff >> e->bitsCount);
     32                e->pos++;
     33        }
    5634}
    5735
    58 #endif /* ENDIAN == HAVE_BIG_ENDIAN */
     36void writeBits (mpc_encoder_t * e, mpc_uint32_t input, unsigned int bits )
     37{
     38        e->outputBits += bits;
     39
     40        if (e->bitsCount + bits > sizeof(e->bitsBuff) * 8) {
     41                int tmp = (sizeof(e->bitsBuff) * 8 - e->bitsCount);
     42                bits -= tmp;
     43                e->bitsBuff = (e->bitsBuff << tmp) | (input >> bits);
     44                e->bitsCount = sizeof(e->bitsBuff) * 8;
     45                emptyBits(e);
     46                input &= (1 << bits) - 1;
     47        }
     48        e->bitsBuff = (e->bitsBuff << bits) | input;
     49        e->bitsCount += bits;
     50}
     51
     52unsigned int encodeSize(mpc_uint64_t size, char * buff, mpc_bool_t addCodeSize)
     53{
     54        unsigned int i = 1;
     55        int j;
     56
     57        if (addCodeSize) {
     58                while ((1 << (7 * i)) - i <= size) i++;
     59                size += i;
     60        } else
     61                while ((1 << (7 * i)) <= size) i++;
     62
     63        for( j = i - 1; j >= 0; j--){
     64                buff[j] = (char) (size | 0x80);
     65                size >>= 7;
     66        }
     67        buff[i - 1] &= 0x7F;
     68
     69        return i;
     70}
     71
     72void writeMagic(mpc_encoder_t * e)
     73{
     74        fwrite("MPCK", sizeof(char), 4, e->outputFile);
     75        e->outputBits += 32;
     76        e->framesInBlock = 0;
     77}
     78
     79void writeBlock ( mpc_encoder_t * e, const char * key, const mpc_bool_t addCRC)
     80{
     81        FILE * fp = e->outputFile;
     82        mpc_uint32_t written = 0;
     83        mpc_uint8_t * datas = e->buffer;
     84        char blockSize[10];
     85        mpc_uint_t len;
     86
     87        writeBits(e, 0, (8 - e->bitsCount) % 8);
     88        emptyBits(e);
     89
     90        // write block header (key / length)
     91        len = encodeSize(e->pos + 2, blockSize, TRUE);
     92        fwrite(key, sizeof(char), 2, fp);
     93        fwrite(blockSize, sizeof(char), len, fp);
     94        e->outputBits += (len + 2) * 8;
    5995
    6096
    61 void
    62 FlushBitstream ( FILE* fp, const mpc_uint32_t* buffer, mpc_size_t words32bit )
    63 {
    64     mpc_size_t           WrittenDwords = 0;
    65     const mpc_uint32_t*  p             = buffer;
    66 #if ENDIAN == HAVE_BIG_ENDIAN
    67     mpc_size_t           CC            = words32bit;
    68 #endif
     97        if (addCRC) {
     98                char tmp[4];
     99                unsigned long CRC32 = crc32((unsigned char *) e->buffer, e->pos);
     100                tmp[0] = (char) (CRC32 >> 24);
     101                tmp[1] = (char) (CRC32 >> 16);
     102                tmp[2] = (char) (CRC32 >> 8);
     103                tmp[3] = (char) CRC32;
     104                fwrite(tmp, sizeof(char), 4, fp);
     105                e->outputBits += 32;
     106        }
    69107
    70 #if ENDIAN == HAVE_BIG_ENDIAN
    71     Change_Endian32 ( (mpc_uint32_t*)buffer, CC );
    72 #endif
    73 
    74     // Write e->Buffer
    75     do {
    76         WrittenDwords = fwrite ( p, sizeof(*buffer), words32bit, fp );
    77         if ( WrittenDwords == 0 ) {
    78                         // FIXME : move stderr_printf to common
    79 //             stderr_printf ( "\b\n WARNING: Disk full?, retry after 10 sec ...\a" );
     108        // write datas
     109        while ( e->pos != 0 ) {
     110                written = fwrite ( datas, sizeof(*e->buffer), e->pos, fp );
     111                if ( written == 0 ) {
    80112                        sprintf(stderr, "\b\n WARNING: Disk full?, retry after 10 sec ...\a");
    81113            sleep (10);
    82114        }
    83         if ( WrittenDwords > 0 ) {
    84             p          += WrittenDwords;
    85             words32bit -= WrittenDwords;
     115                if ( written > 0 ) {
     116                        datas += written;
     117                        e->pos -= written;
    86118        }
    87     } while ( words32bit != 0 );
    88 
    89 #if ENDIAN == HAVE_BIG_ENDIAN
    90     Change_Endian32 ( (mpc_uint32_t*)buffer, CC );
    91 #endif
    92 }
    93 
    94 
    95 void
    96 UpdateHeader ( FILE* fp, mpc_uint32_t Frames, mpc_uint_t ValidSamples )
    97 {
    98     mpc_uint8_t  buff [4];
    99 
    100     // Write framecount to header
    101     if ( fseek ( fp, 4L, SEEK_SET ) < 0 )
    102         return;
    103 
    104     buff [0] = (mpc_uint8_t)(Frames >>  0);
    105     buff [1] = (mpc_uint8_t)(Frames >>  8);
    106     buff [2] = (mpc_uint8_t)(Frames >> 16);
    107     buff [3] = (mpc_uint8_t)(Frames >> 24);
    108 
    109     fwrite ( buff, 1, 4, fp );
    110 
    111     // Write ValidSamples to header
    112     if ( fseek ( fp, 22L, SEEK_SET ) < 0 )
    113         return;
    114     fread ( buff, 1, 2, fp );
    115     if ( ferror(fp) )
    116         return;
    117     if ( fseek ( fp, 22L, SEEK_SET ) < 0 )
    118         return;
    119 
    120     ValidSamples <<= 4;
    121     ValidSamples  |= 0x800F & (((mpc_uint_t) buff[1] << 8) | buff[0]);
    122     buff [0] = (mpc_uint8_t)(ValidSamples >>  0);
    123     buff [1] = (mpc_uint8_t)(ValidSamples >>  8);
    124 
    125     fwrite ( buff, 1, 2, fp );
    126 
    127 
    128     // Set filepointer to end of file (dirty method, should be old position!!)
    129     fseek ( fp, 0L, SEEK_END );
    130 }
    131 
    132 
    133 void WriteBits (mpc_encoder_t * e, const mpc_uint32_t input, const unsigned int bits )
    134 {
    135     e->BufferedBits += bits;
    136     e->filled       -= bits;
    137 
    138     if      ( e->filled > 0 ) {
    139         e->dword  |= input << e->filled;
    140     }
    141     else if ( e->filled < 0 ) {
    142         e->Buffer [e->Zaehler++] = e->dword | ( input >> -e->filled );
    143         e->filled += 32;
    144         e->dword   = input << e->filled;
    145     }
    146     else {
    147         e->Buffer [e->Zaehler++] = e->dword | input;
    148         e->filled  = 32;
    149         e->dword   =  0;
    150     }
    151 }
    152 
    153 // Bits in the original stream have to be 0, maximum X bits allowed to be set in input
    154 // Actual bitstream must have already written ptr[0] and ptr[1]
    155 void WriteBitsAt (mpc_encoder_t * e, const mpc_uint32_t input, const unsigned int bits, BitstreamPos const pos )
    156 {
    157     mpc_uint32_t*     ptr    = pos.ptr;
    158     int           filled = pos.bit - bits;
    159 
    160 //    fprintf ( stderr, "%5u %2u %08lX %2u\n", input, bits, pos.ptr, pos.bit );
    161 
    162     e->Buffer [e->Zaehler] = e->dword;
    163 
    164     if      ( filled > 0 ) {
    165         ptr [0] |= input << (  +filled);
    166     }
    167     else if ( filled < 0 ) {
    168         ptr [0] |= input >> (  -filled);
    169         ptr [1] |= input << (32+filled);
    170     }
    171     else {
    172         ptr [0] |= input;
    173     }
    174 
    175     e->dword = e->Buffer [e->Zaehler];
    176 }
    177 
    178 
    179 void GetBitstreamPos (mpc_encoder_t * e, BitstreamPos* const pos )
    180 {
    181     pos -> ptr = e->Buffer + e->Zaehler;
    182     pos -> bit = e->filled;
     119        }
     120        e->framesInBlock = 0;
    183121}
    184122
Note: See TracChangeset for help on using the changeset viewer.