Reading and converting binary file 2 bits at a time

Gary Willoughby via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 27 04:29:24 PDT 2015


On Thursday, 27 August 2015 at 09:38:52 UTC, Andrew Brown wrote:
> On Thursday, 27 August 2015 at 09:26:55 UTC, rumbu wrote:
>> On Thursday, 27 August 2015 at 09:00:02 UTC, Andrew Brown 
>> wrote:
>>> Hi,
>>>
>>> I need to read a binary file, and then process it two bits at 
>>> a time. But I'm a little stuck on the first step. So far I 
>>> have:
>>>
>>> import std.file;
>>> import std.stdio;
>>>
>>> void main(){
>>>   auto f = std.file.read("binaryfile");
>>>   auto g = cast(bool[])	f;
>>>   writeln(g);
>>> }
>>>
>>> but all the values of g then are just true, could you tell me 
>>> what I'm doing wrong? I've also looked at the bitmanip 
>>> module, I couldn't get it to help, but is that the direction 
>>> I should be looking?
>>>
>>> Thanks very much
>>>
>>> Andrew
>>
>> auto bytes = cast(ubyte[])read("binaryfile");
>> foreach(b; bytes)
>> {
>>     writeln((b & 0xC0) >> 6);  //bits 7, 6
>>     writeln((b & 0x30) >> 4);  //bits 5, 4
>>     writeln((b & 0x0C) >> 2);  //bits 3, 2
>>     writeln((b & 0x03));       //bits 1, 0
>> }
>
> That's lovely, thank you. One quick question, the length of the 
> file is not a multiple of the length of ubyte,  but the cast 
> still seems to work. Do you know how it converts a truncated 
> final section?
>
> Thanks again
>
> Andrew

You can also avoid the bitshifts to make the code a little more 
readable like this:

import std.stdio;
import std.bitmanip;

struct Crumbs
{
	mixin(bitfields!(
		uint, "one", 2,
		uint, "two", 2,
		uint, "three", 2,
		uint, "four", 2
	));
}

void main(string[] args)
{
	ubyte[] buffer = [123, 12, 126, 244, 35];

	foreach (octet; buffer)
	{
		auto crumbs = Crumbs(octet);
		ubyte* representation = cast(ubyte*)&crumbs;

		writefln("Crumb:       %08b", *representation);
		writefln("Crumb one:   %s", crumbs.one);
		writefln("Crumb two:   %s", crumbs.two);
		writefln("Crumb three: %s", crumbs.three);
		writefln("Crumb four:  %s", crumbs.four);
		writeln("---------------------");
	}
}

Now you can read a crumb at a time.


More information about the Digitalmars-d-learn mailing list