Re: How to read 12 bits from a stream ?

• To: mathgroup at smc.vnet.net
• Subject: [mg131884] Re: How to read 12 bits from a stream ?
• From: Vince Virgilio <blueschi at gmail.com>
• Date: Wed, 23 Oct 2013 23:45:34 -0400 (EDT)
• Delivered-to: l-mathgroup@mail-archive0.wolfram.com
• Delivered-to: l-mathgroup@wolfram.com
• Delivered-to: mathgroup-outx@smc.vnet.net
• Delivered-to: mathgroup-newsendx@smc.vnet.net
• References: <l450c4\$shl\$1@smc.vnet.net>

```Some sketchy advice . . .

16.1 MB is a tiny amount of data.

I'd read the entire file into a string, e.g. Import[filename, "String"], then to bytes with ToCharacterCode, then use logical bit operations to extract your bit-fields.

Here's some code that might help you think about the problem. It assumes the binary data from ToCharacterCode has been paired up into words (from original bytes). So bLo and bHi are in [1, 16]. The code is listable. It can be very efficient if your data can be broken into a sequence of 'records' of identical length. Put the offset within a record in first dimension and the record # in the second dimension.

left[n_][b_] := BitShiftLeft[b, n];

right[n_][b_] := BitShiftRight[b, n];

(* n is # bits, p is zero-based position *)
mask[n_, p_][b_] := BitAnd[b, left[p][2^n - 1]] // right[p];

toU16[{b1_, b2_, ___}] := left[8]@b1 + b2;

toU32[{w1_, w2_, ___}] := left[16]@w1 + w2;

field[w_, b_][data_] := field[w, {b, b}][data];

(* bLo, bHi in [1, 16] *)
field[w_, {bLo_, bHi_}][data_] :=
data[[w]] // mask[bHi - bLo + 1, 16 - bHi];

Vince

On Tuesday, October 22, 2013 12:53:24 AM UTC-4, J=E1nos L=F6bb wrote:
> Hi,
>
>
>
> I am trying to read a mixed file - binary and text -  with OpenRead and Read and BinaryRead, but I am not seeing a seek option, that is to move the pointer inside the file where I want it to be.  Of course I can do a read in a loop with a counter, but I hoped there is a better way to do it.
>
>
>
> The file is 16.1MB, the first 912 elements are characters and binary mixed, followed by 16MB binary section.  The binary in this second section is  packed in the way that 2 times 12 bits  of little endian value is packed into 3 bytes.  I need to unpack them and put them into big endian order.  I am not seeing how can I read 12 bits at once with BinaryRead, it is aligned at the multiples of 8 bits.
>
>
>
> Any good tip ?
>
>
>