| /* libFLAC - Free Lossless Audio Coder library |
| * Copyright (C) 2000 Josh Coalson |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #include <assert.h> |
| #include <stdlib.h> /* for malloc() */ |
| #include <string.h> /* for memcpy(), memset() */ |
| #include "private/bitbuffer.h" |
| |
| static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = 65536; /* bytes */ |
| |
| #ifdef min |
| #undef min |
| #endif |
| #define min(x,y) ((x)<(y)?(x):(y)) |
| #ifdef max |
| #undef max |
| #endif |
| #define max(x,y) ((x)>(y)?(x):(y)) |
| |
| static bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity) |
| { |
| byte *new_buffer; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| if(bb->capacity == new_capacity) |
| return true; |
| |
| new_buffer = (byte*)malloc(sizeof(byte) * new_capacity); |
| if(new_buffer == 0) |
| return false; |
| memset(new_buffer, 0, new_capacity); |
| memcpy(new_buffer, bb->buffer, sizeof(byte)*min(bb->bytes+(bb->bits?1:0), new_capacity)); |
| if(new_capacity < bb->bytes+(bb->bits?1:0)) { |
| bb->bytes = new_capacity; |
| bb->bits = 0; |
| bb->total_bits = (new_capacity<<3); |
| } |
| if(new_capacity < bb->consumed_bytes+(bb->consumed_bits?1:0)) { |
| bb->consumed_bytes = new_capacity; |
| bb->consumed_bits = 0; |
| bb->total_consumed_bits = (new_capacity<<3); |
| } |
| bb->buffer = new_buffer; |
| bb->capacity = new_capacity; |
| return true; |
| } |
| |
| static bool bitbuffer_grow_(FLAC__BitBuffer *bb, unsigned min_bytes_to_add) |
| { |
| unsigned new_capacity; |
| |
| assert(min_bytes_to_add > 0); |
| |
| new_capacity = max(bb->capacity * 4, bb->capacity + min_bytes_to_add); |
| return bitbuffer_resize_(bb, new_capacity); |
| } |
| |
| static bool bitbuffer_ensure_size_(FLAC__BitBuffer *bb, unsigned bits_to_add) |
| { |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| if((bb->capacity<<3) < bb->total_bits + bits_to_add) |
| return bitbuffer_grow_(bb, (bits_to_add>>3)+2); |
| else |
| return true; |
| } |
| |
| static bool bitbuffer_read_from_client_(FLAC__BitBuffer *bb, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| unsigned bytes; |
| |
| /* first shift the unconsumed buffer data toward the front as much as possible */ |
| if(bb->total_consumed_bits >= 8) { |
| unsigned l = 0, r = bb->consumed_bytes, r_end = bb->bytes; |
| for( ; r < r_end; l++, r++) |
| bb->buffer[l] = bb->buffer[r]; |
| for( ; l < r_end; l++) |
| bb->buffer[l] = 0; |
| bb->bytes -= bb->consumed_bytes; |
| bb->total_bits -= (bb->consumed_bytes<<3); |
| bb->consumed_bytes = 0; |
| bb->total_consumed_bits = bb->consumed_bits; |
| } |
| /* grow if we need to */ |
| if(bb->capacity <= 1) { |
| if(!bitbuffer_resize_(bb, 16)) |
| return false; |
| } |
| /* finally, read in some data; if OK, go back to read_bit_, else fail */ |
| bytes = bb->capacity - bb->bytes; |
| if(!read_callback(bb->buffer+bb->bytes, &bytes, client_data)) |
| return false; |
| bb->bytes += bytes; |
| bb->total_bits += (bytes<<3); |
| return true; |
| } |
| |
| void FLAC__bitbuffer_init(FLAC__BitBuffer *bb) |
| { |
| assert(bb != 0); |
| bb->buffer = 0; |
| bb->capacity = 0; |
| bb->bytes = bb->bits = bb->total_bits = 0; |
| bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; |
| } |
| |
| bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const byte buffer[], unsigned bytes) |
| { |
| assert(bb != 0); |
| FLAC__bitbuffer_init(bb); |
| if(bytes == 0) |
| return true; |
| else { |
| assert(buffer != 0); |
| bb->buffer = (byte*)malloc(sizeof(byte)*bytes); |
| if(bb->buffer == 0) |
| return false; |
| memcpy(bb->buffer, buffer, sizeof(byte)*bytes); |
| bb->capacity = bb->bytes = bytes; |
| bb->bits = 0; |
| bb->total_bits = (bytes<<3); |
| bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; |
| return true; |
| } |
| } |
| |
| bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src) |
| { |
| static byte mask_[9] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; |
| unsigned bits_to_add = src->total_bits - src->total_consumed_bits; |
| assert(dest != 0); |
| assert(src != 0); |
| |
| if(bits_to_add == 0) |
| return true; |
| if(dest->bits != src->consumed_bits) |
| return false; |
| if(!bitbuffer_ensure_size_(dest, bits_to_add)) |
| return false; |
| if(dest->bits == 0) { |
| memcpy(dest->buffer+dest->bytes, src->buffer+src->consumed_bytes, src->bytes-src->consumed_bytes + ((src->bits)? 1:0)); |
| } |
| else if(dest->bits + bits_to_add > 8) { |
| dest->buffer[dest->bytes] <<= (8 - dest->bits); |
| dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[8-dest->bits]); |
| memcpy(dest->buffer+dest->bytes+1, src->buffer+src->consumed_bytes+1, src->bytes-src->consumed_bytes-1 + ((src->bits)? 1:0)); |
| } |
| else { |
| dest->buffer[dest->bytes] <<= bits_to_add; |
| dest->buffer[dest->bytes] |= (src->buffer[src->consumed_bytes] & mask_[bits_to_add]); |
| } |
| dest->bits = src->bits; |
| dest->total_bits += bits_to_add; |
| dest->bytes = dest->total_bits / 8; |
| |
| return true; |
| } |
| |
| void FLAC__bitbuffer_free(FLAC__BitBuffer *bb) |
| { |
| assert(bb != 0); |
| if(bb->buffer != 0) |
| free(bb->buffer); |
| bb->buffer = 0; |
| bb->capacity = 0; |
| bb->bytes = bb->bits = bb->total_bits = 0; |
| bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; |
| } |
| |
| bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb) |
| { |
| if(bb->buffer == 0) { |
| bb->capacity = FLAC__BITBUFFER_DEFAULT_CAPACITY; |
| bb->buffer = (byte*)malloc(sizeof(byte) * bb->capacity); |
| if(bb->buffer == 0) |
| return false; |
| memset(bb->buffer, 0, bb->capacity); |
| } |
| else { |
| memset(bb->buffer, 0, bb->bytes + (bb->bits?1:0)); |
| } |
| bb->bytes = bb->bits = bb->total_bits = 0; |
| bb->consumed_bytes = bb->consumed_bits = bb->total_consumed_bits = 0; |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src) |
| { |
| if(dest->capacity < src->capacity) |
| if(!bitbuffer_resize_(dest, src->capacity)) |
| return false; |
| memcpy(dest->buffer, src->buffer, sizeof(byte)*min(src->capacity, src->bytes+1)); |
| dest->bytes = src->bytes; |
| dest->bits = src->bits; |
| dest->total_bits = src->total_bits; |
| dest->consumed_bytes = src->consumed_bytes; |
| dest->consumed_bits = src->consumed_bits; |
| dest->total_consumed_bits = src->total_consumed_bits; |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits) |
| { |
| unsigned n, k; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| if(bits == 0) |
| return true; |
| if(!bitbuffer_ensure_size_(bb, bits)) |
| return false; |
| bb->total_bits += bits; |
| while(bits > 0) { |
| n = min(8 - bb->bits, bits); |
| k = bits - n; |
| bb->buffer[bb->bytes] <<= n; |
| bits -= n; |
| bb->bits += n; |
| if(bb->bits == 8) { |
| bb->bytes++; |
| bb->bits = 0; |
| } |
| } |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, uint32 val, unsigned bits) |
| { |
| static uint32 mask[] = { |
| 0, |
| 0x00000001, 0x00000003, 0x00000007, 0x0000000F, |
| 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, |
| 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, |
| 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, |
| 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, |
| 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, |
| 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, |
| 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF |
| }; |
| unsigned n, k; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 32); |
| if(bits == 0) |
| return true; |
| if(!bitbuffer_ensure_size_(bb, bits)) |
| return false; |
| val &= mask[bits]; |
| bb->total_bits += bits; |
| while(bits > 0) { |
| n = 8 - bb->bits; |
| if(n == 8) { /* i.e. bb->bits == 0 */ |
| if(bits < 8) { |
| bb->buffer[bb->bytes] = val; |
| bb->bits = bits; |
| break; |
| } |
| else if(bits == 8) { |
| bb->buffer[bb->bytes++] = val; |
| break; |
| } |
| else { |
| k = bits - 8; |
| bb->buffer[bb->bytes++] = val >> k; |
| val &= (~(0xffffffff << k)); |
| bits -= 8; |
| } |
| } |
| else if(bits <= n) { |
| bb->buffer[bb->bytes] <<= bits; |
| bb->buffer[bb->bytes] |= val; |
| if(bits == n) { |
| bb->bytes++; |
| bb->bits = 0; |
| } |
| else |
| bb->bits += bits; |
| break; |
| } |
| else { |
| k = bits - n; |
| bb->buffer[bb->bytes] <<= n; |
| bb->buffer[bb->bytes] |= (val>>k); |
| val &= (~(0xffffffff << k)); |
| bits -= n; |
| bb->bytes++; |
| bb->bits = 0; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, int32 val, unsigned bits) |
| { |
| return FLAC__bitbuffer_write_raw_uint32(bb, (uint32)val, bits); |
| } |
| |
| bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, uint64 val, unsigned bits) |
| { |
| static uint64 mask[] = { |
| 0, |
| 0x0000000000000001, 0x0000000000000003, 0x0000000000000007, 0x000000000000000F, |
| 0x000000000000001F, 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF, |
| 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF, 0x0000000000000FFF, |
| 0x0000000000001FFF, 0x0000000000003FFF, 0x0000000000007FFF, 0x000000000000FFFF, |
| 0x000000000001FFFF, 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF, |
| 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF, 0x0000000000FFFFFF, |
| 0x0000000001FFFFFF, 0x0000000003FFFFFF, 0x0000000007FFFFFF, 0x000000000FFFFFFF, |
| 0x000000001FFFFFFF, 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF, |
| 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF, 0x0000000FFFFFFFFF, |
| 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF, 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, |
| 0x000001FFFFFFFFFF, 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF, |
| 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF, 0x0000FFFFFFFFFFFF, |
| 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF, 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, |
| 0x001FFFFFFFFFFFFF, 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF, |
| 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF, 0x0FFFFFFFFFFFFFFF, |
| 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF |
| }; |
| unsigned n, k; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 64); |
| if(bits == 0) |
| return true; |
| if(!bitbuffer_ensure_size_(bb, bits)) |
| return false; |
| val &= mask[bits]; |
| bb->total_bits += bits; |
| while(bits > 0) { |
| if(bb->bits == 0) { |
| if(bits < 8) { |
| bb->buffer[bb->bytes] = val; |
| bb->bits = bits; |
| break; |
| } |
| else if(bits == 8) { |
| bb->buffer[bb->bytes++] = val; |
| break; |
| } |
| else { |
| k = bits - 8; |
| bb->buffer[bb->bytes++] = val >> k; |
| val &= (~(0xffffffffffffffff << k)); |
| bits -= 8; |
| } |
| } |
| else { |
| n = min(8 - bb->bits, bits); |
| k = bits - n; |
| bb->buffer[bb->bytes] <<= n; |
| bb->buffer[bb->bytes] |= (val>>k); |
| val &= (~(0xffffffffffffffff << k)); |
| bits -= n; |
| bb->bits += n; |
| if(bb->bits == 8) { |
| bb->bytes++; |
| bb->bits = 0; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, int64 val, unsigned bits) |
| { |
| return FLAC__bitbuffer_write_raw_uint64(bb, (uint64)val, bits); |
| } |
| |
| bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) |
| { |
| unsigned bits, msbs; |
| uint32 pattern; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| /* init pattern with sign bit */ |
| if(val < 0) { |
| pattern = 1; |
| val = -val; |
| } |
| else |
| pattern = 0; |
| |
| msbs = val >> parameter; |
| bits = 2 + parameter + msbs; |
| |
| if(bits <= 32) { |
| pattern = (pattern << parameter) | (val & ((1<<parameter)-1)); |
| pattern = (pattern << (msbs+1)) | 1; |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, bits)) |
| return false; |
| } |
| else { |
| /* write the sign bit */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, 1)) |
| return false; |
| /* write the binary LSBs */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, val & ((1<<parameter)-1), parameter)) |
| return false; |
| /* write the unary MSBs */ |
| if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) |
| return false; |
| /* write the end bit */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1)) |
| return false; |
| } |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, bool *overflow) |
| { |
| unsigned bits, msbs; |
| uint32 pattern; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| *overflow = false; |
| |
| /* init pattern with sign bit */ |
| if(val < 0) { |
| pattern = 1; |
| val = -val; |
| } |
| else |
| pattern = 0; |
| |
| msbs = val >> parameter; |
| bits = 2 + parameter + msbs; |
| |
| if(bits <= 32) { |
| pattern = (pattern << parameter) | (val & ((1<<parameter)-1)); |
| pattern = (pattern << (msbs+1)) | 1; |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, bits)) |
| return false; |
| } |
| else if(bits > max_bits) { |
| *overflow = true; |
| return true; |
| } |
| else { |
| /* write the sign bit */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, 1)) |
| return false; |
| /* write the binary LSBs */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, val & ((1<<parameter)-1), parameter)) |
| return false; |
| /* write the unary MSBs */ |
| if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) |
| return false; |
| /* write the end bit */ |
| if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1)) |
| return false; |
| } |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, uint32 val) |
| { |
| bool ok = 1; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(!(val & 0x80000000)); /* this version only handles 31 bits */ |
| |
| if(val < 0x80) { |
| return FLAC__bitbuffer_write_raw_uint32(bb, val, 8); |
| } |
| else if(val < 0x800) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (val>>6), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); |
| } |
| else if(val < 0x10000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (val>>12), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); |
| } |
| else if(val < 0x200000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (val>>18), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); |
| } |
| else if(val < 0x4000000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (val>>24), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); |
| } |
| else { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (val>>30), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>24)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); |
| } |
| |
| return ok; |
| } |
| |
| bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, uint64 val) |
| { |
| bool ok = 1; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(!(val & 0xFFFFFFF000000000)); /* this version only handles 36 bits */ |
| |
| if(val < 0x80) { |
| return FLAC__bitbuffer_write_raw_uint32(bb, (uint32)val, 8); |
| } |
| else if(val < 0x800) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (uint32)(val>>6), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| else if(val < 0x10000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (uint32)(val>>12), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| else if(val < 0x200000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (uint32)(val>>18), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| else if(val < 0x4000000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (uint32)(val>>24), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| else if(val < 0x80000000) { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (uint32)(val>>30), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>24)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| else { |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFE, 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>30)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>24)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>18)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>12)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)((val>>6)&0x3F), 8); |
| ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (uint32)(val&0x3F), 8); |
| } |
| |
| return ok; |
| } |
| |
| bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb) |
| { |
| /* 0-pad to byte boundary */ |
| if(bb->bits != 0) |
| return FLAC__bitbuffer_write_zeroes(bb, 8 - bb->bits); |
| else |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 }; |
| |
| /* to avoid a drastic speed penalty we don't: |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| assert(bb->bits == 0); |
| */ |
| |
| read_bit_: |
| if(bb->total_consumed_bits < bb->total_bits) { |
| *val = (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0; |
| return true; |
| } |
| else { |
| if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) |
| return false; |
| goto read_bit_; |
| } |
| } |
| |
| bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 }; |
| |
| /* to avoid a drastic speed penalty we don't: |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| assert(bb->bits == 0); |
| */ |
| |
| read_bit_: |
| if(bb->total_consumed_bits < bb->total_bits) { |
| *val = (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0; |
| bb->consumed_bits++; |
| if(bb->consumed_bits == 8) { |
| bb->consumed_bytes++; |
| bb->consumed_bits = 0; |
| } |
| bb->total_consumed_bits++; |
| return true; |
| } |
| else { |
| if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) |
| return false; |
| goto read_bit_; |
| } |
| } |
| |
| bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 }; |
| |
| /* to avoid a drastic speed penalty we don't: |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| assert(bb->bits == 0); |
| */ |
| |
| read_bit_: |
| if(bb->total_consumed_bits < bb->total_bits) { |
| *val <<= 1; |
| *val |= (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0; |
| bb->consumed_bits++; |
| if(bb->consumed_bits == 8) { |
| bb->consumed_bytes++; |
| bb->consumed_bits = 0; |
| } |
| bb->total_consumed_bits++; |
| return true; |
| } |
| else { |
| if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) |
| return false; |
| goto read_bit_; |
| } |
| } |
| |
| bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| static byte mask[] = { 128, 64, 32, 16, 8, 4, 2, 1 }; |
| |
| /* to avoid a drastic speed penalty we don't: |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| assert(bb->bits == 0); |
| */ |
| |
| read_bit_: |
| if(bb->total_consumed_bits < bb->total_bits) { |
| *val <<= 1; |
| *val |= (bb->buffer[bb->consumed_bytes] & mask[bb->consumed_bits])? 1 : 0; |
| bb->consumed_bits++; |
| if(bb->consumed_bits == 8) { |
| bb->consumed_bytes++; |
| bb->consumed_bits = 0; |
| } |
| bb->total_consumed_bits++; |
| return true; |
| } |
| else { |
| if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) |
| return false; |
| goto read_bit_; |
| } |
| } |
| |
| bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, uint32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| unsigned i; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 32); |
| |
| *val = 0; |
| for(i = 0; i < bits; i++) { |
| if(!FLAC__bitbuffer_read_bit_to_uint32(bb, val, read_callback, client_data)) |
| return false; |
| } |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, int32 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| unsigned i; |
| uint32 x; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 32); |
| |
| x = 0; |
| for(i = 0; i < bits; i++) { |
| if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &x, read_callback, client_data)) |
| return false; |
| } |
| /* fix the sign */ |
| i = 32 - bits; |
| if(i) { |
| x <<= i; |
| *val = (int32)x; |
| *val >>= i; |
| } |
| else |
| *val = (int32)x; |
| |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, uint64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| unsigned i; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 64); |
| |
| *val = 0; |
| for(i = 0; i < bits; i++) { |
| if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data)) |
| return false; |
| } |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, int64 *val, unsigned bits, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| unsigned i; |
| uint64 x; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| assert(bits <= 64); |
| |
| x = 0; |
| for(i = 0; i < bits; i++) { |
| if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &x, read_callback, client_data)) |
| return false; |
| } |
| /* fix the sign */ |
| i = 64 - bits; |
| if(i) { |
| x <<= i; |
| *val = (int64)x; |
| *val >>= i; |
| } |
| else |
| *val = (int64)x; |
| |
| return true; |
| } |
| |
| bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data) |
| { |
| uint32 sign = 0, lsbs, msbs = 0; |
| unsigned bit; |
| |
| assert(bb != 0); |
| assert(bb->buffer != 0); |
| |
| /* read the sign bit */ |
| if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &sign, read_callback, client_data)) |
| return false; |
| /* read the binary LSBs */ |
| if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, parameter, read_callback, client_data)) |
| return false; |
| /* read the unary MSBs and end bit */ |
| while(1) { |
| if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data)) |
| return false; |
| if(bit) |
| break; |
| else |
| msbs++; |
| } |
| /* compose the value */ |
| *val = (msbs << parameter) | lsbs; |
| if(sign) |
| *val = -(*val); |
| |
| return true; |
| } |
| |
| /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */ |
| bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, uint32 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen) |
| { |
| uint32 v = 0; |
| uint32 x; |
| unsigned i; |
| |
| if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) |
| return false; |
| if(raw) |
| raw[(*rawlen)++] = (byte)x; |
| if(!(x & 0x80)) { /* 0xxxxxxx */ |
| v = x; |
| i = 0; |
| } |
| else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ |
| v = x & 0x1F; |
| i = 1; |
| } |
| else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ |
| v = x & 0x0F; |
| i = 2; |
| } |
| else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ |
| v = x & 0x07; |
| i = 3; |
| } |
| else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ |
| v = x & 0x03; |
| i = 4; |
| } |
| else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ |
| v = x & 0x01; |
| i = 5; |
| } |
| else |
| goto invalid_; |
| for( ; i; i--) { |
| if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) |
| return false; |
| if(raw) |
| raw[(*rawlen)++] = (byte)x; |
| if(!(x & 0x80) || (x & 0x40)) /* 10xxxxxx */ |
| goto invalid_; |
| v <<= 6; |
| v |= (x & 0x3F); |
| } |
| *val = v; |
| return true; |
| invalid_: |
| *val = 0xffffffff; |
| return true; |
| } |
| |
| /* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */ |
| bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, uint64 *val, bool (*read_callback)(byte buffer[], unsigned *bytes, void *client_data), void *client_data, byte *raw, unsigned *rawlen) |
| { |
| uint64 v = 0; |
| uint32 x; |
| unsigned i; |
| |
| if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) |
| return false; |
| if(raw) |
| raw[(*rawlen)++] = (byte)x; |
| if(!(x & 0x80)) { /* 0xxxxxxx */ |
| v = x; |
| i = 0; |
| } |
| else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ |
| v = x & 0x1F; |
| i = 1; |
| } |
| else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ |
| v = x & 0x0F; |
| i = 2; |
| } |
| else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ |
| v = x & 0x07; |
| i = 3; |
| } |
| else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ |
| v = x & 0x03; |
| i = 4; |
| } |
| else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ |
| v = x & 0x01; |
| i = 5; |
| } |
| else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */ |
| v = 0; |
| i = 6; |
| } |
| else |
| goto invalid_; |
| for( ; i; i--) { |
| if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) |
| return false; |
| if(raw) |
| raw[(*rawlen)++] = (byte)x; |
| if(!(x & 0x80) || (x & 0x40)) /* 10xxxxxx */ |
| goto invalid_; |
| v <<= 6; |
| v |= (x & 0x3F); |
| } |
| *val = v; |
| return true; |
| invalid_: |
| *val = 0xffffffff; |
| return true; |
| } |
| |
| void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out) |
| { |
| unsigned i, j; |
| if(bb == 0) { |
| fprintf(out, "bitbuffer is NULL\n"); |
| } |
| else { |
| fprintf(out, "bitbuffer: capacity=%u bytes=%u bits=%u total_bits=%u consumed: bytes=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->bytes, bb->bits, bb->total_bits, bb->consumed_bytes, bb->consumed_bits, bb->total_consumed_bits); |
| for(i = 0; i < bb->bytes; i++) { |
| fprintf(out, "%08X: ", i); |
| for(j = 0; j < 8; j++) |
| if(i*8+j < bb->total_consumed_bits) |
| fprintf(out, "."); |
| else |
| fprintf(out, "%01u", bb->buffer[i] & (1 << (8-j-1)) ? 1:0); |
| fprintf(out, "\n"); |
| } |
| if(bb->bits > 0) { |
| fprintf(out, "%08X: ", i); |
| for(j = 0; j < bb->bits; j++) |
| if(i*8+j < bb->total_consumed_bits) |
| fprintf(out, "."); |
| else |
| fprintf(out, "%01u", bb->buffer[i] & (1 << (bb->bits-j-1)) ? 1:0); |
| fprintf(out, "\n"); |
| } |
| } |
| } |