Source code for eyed3.utils.binfuncs

################################################################################
#  Copyright (C) 2001  Ryan Finne <ryan@finnie.org>
#  Copyright (C) 2002-2011  Travis Shirk <travis@pobox.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program 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 General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, see <http://www.gnu.org/licenses/>.
#
################################################################################
from ..compat import intToByteString, BytesType, byteiter


[docs]def bytes2bin(bytes, sz=8): '''Accepts a string of ``bytes`` (chars) and returns an array of bits representing the bytes in big endian byte order. An optional max ``sz`` for each byte (default 8 bits/byte) which can be used to mask out higher bits.''' if sz < 1 or sz > 8: raise ValueError("Invalid sz value: %d" % sz) ''' # I was willing to bet this implementation was gonna be faster, tis not retval = [] for bite in bytes: bits = [int(b) for b in bin(ord(bite))[2:].zfill(8)][-sz:] assert(len(bits) == sz) retval.extend(bits) return retval ''' retVal = [] for b in byteiter(bytes): bits = [] b = ord(b) while b > 0: bits.append(b & 1) b >>= 1 if len(bits) < sz: bits.extend([0] * (sz - len(bits))) elif len(bits) > sz: bits = bits[:sz] # Big endian byte order. bits.reverse() retVal.extend(bits) return retVal
# Convert an array of bits (MSB first) into a string of characters.
[docs]def bin2bytes(x): bits = [] bits.extend(x) bits.reverse() i = 0 out = b'' multi = 1 ttl = 0 for b in bits: i += 1 ttl += b * multi multi *= 2 if i == 8: i = 0 out += intToByteString(ttl) multi = 1 ttl = 0 if multi > 1: out += intToByteString(ttl) out = bytearray(out) out.reverse() out = BytesType(out) return out
[docs]def bin2dec(x): '''Convert ``x``, an array of "bits" (MSB first), to it's decimal value.''' bits = [] bits.extend(x) bits.reverse() # MSB multi = 1 value = 0 for b in bits: value += b * multi multi *= 2 return value
[docs]def bytes2dec(bytes, sz=8): return bin2dec(bytes2bin(bytes, sz))
[docs]def dec2bin(n, p=1): '''Convert a decimal value ``n`` to an array of bits (MSB first). Optionally, pad the overall size to ``p`` bits.''' assert(n >= 0) retVal = [] while n > 0: retVal.append(n & 1) n >>= 1 if p > 0: retVal.extend([0] * (p - len(retVal))) retVal.reverse() return retVal
[docs]def dec2bytes(n, p=1): return bin2bytes(dec2bin(n, p))
[docs]def bin2synchsafe(x): '''Convert ``x``, a list of bits (MSB first), to a synch safe list of bits. (section 6.2 of the ID3 2.4 spec).''' n = bin2dec(x) if len(x) > 32 or n > 268435456: # 2^28 raise ValueError("Invalid value: %s" % str(x)) elif len(x) < 8: return x bites = b"" bites += intToByteString((n >> 21) & 0x7f) bites += intToByteString((n >> 14) & 0x7f) bites += intToByteString((n >> 7) & 0x7f) bites += intToByteString((n >> 0) & 0x7f) bits = bytes2bin(bites) assert(len(bits) == 32) return bits