repack ubyte[] to use only 7 bits
Charles Hixson via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Dec 6 10:12:08 PST 2014
Is there a standard way to do this? The code below is untested, as I
haven't yet written the x7to8 routine, and came up with a better way to
do what this was to accomplish, but it feels as if this should be
somewhere in the standard library, if I could only find it.
/** Repack the data from an array of ubytes into an array of ubytes of
* which only the last 7 are significant. The high bit will be set only
* if the byte would otherwise be zero. */
byte[] x8to7 (ubyte[] bin)
{
ubyte[] bout;
// bit masks: 0 => 0xfe = 11111110, 0x00 = 00000000
// 1 => 0x7f = 01111111, 0x00 = 00000000
// 2 => 0x3f = 00111111, 0x80 = 10000000
// 3 => 0x1f = 00011111, 0xc0 = 11000000
// 4 => 0x0f = 00001111, 0xe0 = 11100000
// 5 => 0x07 = 00000111, 0xf0 = 11110000
// 6 => 0x03 = 00000011, 0xf8 = 11111000
// 7 => 0x01 = 00000001, 0xfc = 11111100
if (bin.length < 1) return bout;
int fByte, fBit;
while (fByte < bin.length)
{ if (fByte + 1 == bin.length && fBit > 1) break;
ubyte b;
switch (fBit)
{ case 0:
b = bin[fByte] / 2;
break;
case 1:
b = bin[fByte] & 0x7f;
break;
case 2:
ubyte b1 = (bin[fByte] & 0x3f) << 1;
ubyte b2 = (bin[fByte + 1] & 0x80) >>> 7;
b ~= (b1 | b2);
break;
case 3:
ubyte b1 = (bin[fByte] & 0x1f) << 2;
ubyte b2 = (bin[fByte + 1] & 0xc0) >>> 6;
b ~= (b1 | b2);
break;
case 4:
ubyte b1 = (bin[fByte] & 0x0f) << 3;
ubyte b2 = (bin[fByte + 1] & 0xe0) >>> 5;
b ~= (b1 | b2);
break;
case 5:
ubyte b1 = (bin[fByte] & 0x07) << 4;
ubyte b2 = (bin[fByte + 1] & 0xf0) >>> 4;
b ~= (b1 | b2);
break;
case 6:
ubyte b1 = (bin[fByte] & 0x03) << 5;
ubyte b2 = (bin[fByte + 1] & 0xf8) >>> 3;
b ~= (b1 | b2);
break;
case 7:
ubyte b1 = (bin[fByte] & 0x01) << 6;
ubyte b2 = (bin[fByte + 1] & 0xfc) >>> 2;
b ~= (b1 | b2);
break;
default:
assert (false, "This path should never be taken");
} // switch (fBit)
if (b == 0) bout ~= 0x80;
else bout ~= b;
fBit = fBit + 7;
if (fBit > 7)
{ fByte++;
fBit -= 7;
}
}
}
More information about the Digitalmars-d-learn
mailing list