Changeset 78 for mppenc/branches/r2d/libmpcenc/bitstream.c
- Timestamp:
- 10/27/06 18:42:05 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
mppenc/branches/r2d/libmpcenc/bitstream.c
r71 r78 23 23 #include "stdio.h" 24 24 25 unsigned long crc32(unsigned char *buf, int len); 25 26 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 ) 27 void emptyBits(mpc_encoder_t * e) 38 28 { 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 } 56 34 } 57 35 58 #endif /* ENDIAN == HAVE_BIG_ENDIAN */ 36 void 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 52 unsigned 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 72 void writeMagic(mpc_encoder_t * e) 73 { 74 fwrite("MPCK", sizeof(char), 4, e->outputFile); 75 e->outputBits += 32; 76 e->framesInBlock = 0; 77 } 78 79 void 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; 59 95 60 96 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 } 69 107 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 ) { 80 112 sprintf(stderr, "\b\n WARNING: Disk full?, retry after 10 sec ...\a"); 81 113 sleep (10); 82 114 } 83 if ( WrittenDwords> 0 ) {84 p += WrittenDwords;85 words32bit -= WrittenDwords;115 if ( written > 0 ) { 116 datas += written; 117 e->pos -= written; 86 118 } 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; 183 121 } 184 122
Note: See TracChangeset
for help on using the changeset viewer.