/** 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; } } }
repack ubyte[] to use only 7 bits
Charles Hixson via Digitalmars-d-learn Sat, 13 Dec 2014 02:10:06 -0800
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 ubyte[] to use only 7 bits Charles Hixson via Digitalmars-d-learn
- Re: repack ubyte[] to use only... bearophile via Digitalmars-d-learn
- Re: repack ubyte[] to use ... Charles Hixson via Digitalmars-d-learn
- repack ubyte[] to use only 7 b... Charles Hixson via Digitalmars-d-learn
- Re: repack ubyte[] to use only... Manolo via Digitalmars-d-learn
- Re: repack ubyte[] to use ... Manolo via Digitalmars-d-learn
- Re: repack ubyte[] to use ... Charles Hixson via Digitalmars-d-learn
- Re: repack ubyte[] to use ... Manolo via Digitalmars-d-learn