Source code for pylablib.core.utils.strpack

"""
Utilities for packing values into bitstrings.
Small extension of the struct module.
"""

import struct
import numpy as np
from . import funcargparse


struct_descriptors={("i",1):"b",("i",2):"h",("i",4):"i",("i",8):"q",
                 ("u",1):"B",("u",2):"H",("u",4):"I",("u",8):"Q",
                 ("f",4):"f",("f",8):"d"}

[docs] def int2bytes(val, l, bo=">"): """ Convert integer into a list of bytes of length `l`. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ funcargparse.check_parameter_range(bo,"bo","<>") bs=[(val>>(n*8))&0xFF for n in range(l)] return bs if bo=="<" else bs[::-1]
[docs] def bytes2int(val, bo=">"): """ Convert a list of bytes into an integer. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ funcargparse.check_parameter_range(bo,"bo","<>") if bo=="<": bo=bo[::-1] return sum([(b<<(n*8)) for n,b in enumerate(val)])
[docs] def int2bits(val, l, bo=">"): """ Convert integer into a list of bits of length `l`. `bo` determines byte (and bit) order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ funcargparse.check_parameter_range(bo,"bo","<>") bs=[bool((val>>n)&0x01) for n in range(l)] return bs if bo=="<" else bs[::-1]
[docs] def bits2int(val, bo=">"): """ Convert a list of bits into an integer. `bo` determines byte (and bit) order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ funcargparse.check_parameter_range(bo,"bo","<>") if bo=="<": bo=bo[::-1] return sum([(int(b)<<n) for n,b in enumerate(val)])
[docs] def pack_uint(val, l, bo=">"): """ Convert an unsigned integer into a bytestring of length `l`. Return ``bytes`` object. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ fmt="u",l if fmt in struct_descriptors: fmt=bo+struct_descriptors[fmt] return struct.pack(fmt,val) bs=int2bytes(val,l,bo) return bytes(bs)
[docs] def pack_int(val, l, bo=">"): """ Convert a signed integer into a bytestring of length `l`. Return ``bytes`` object. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ return pack_uint(val%(1<<l*8),l,bo)
[docs] def unpack_uint(msg, bo=">"): """ Convert a bytestring into an unsigned integer. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ fmt="u",len(msg) if fmt in struct_descriptors: fmt=bo+struct_descriptors[fmt] return struct.unpack(fmt,msg)[0] return bytes2int(bytes(msg),bo)
[docs] def unpack_int(msg, bo=">"): """ Convert a bytestring into an signed integer. `bo` determines byte order: ``'>'`` is big-endian (MSB first), ``'<'`` is little-endian (LSB first). """ val=unpack_uint(msg,bo) maxint=1<<(len(msg)*8-1) return ((val+maxint)%(maxint*2))-maxint
[docs] def unpack_numpy_u12bit(buffer, byteorder="<", count=-1): u8count=count*3//2 if count>0 else -1 data=np.frombuffer(buffer,dtype="u1",count=u8count) fst_uint8,mid_uint8,lst_uint8=np.reshape(data,(len(data)//3,3)).astype(np.uint16).T if byteorder==">": fst_uint12=(fst_uint8<<4)+(mid_uint8>>4) snd_uint12=((mid_uint8%16)<<8)+lst_uint8 else: fst_uint12=fst_uint8+((mid_uint8>>4)<<8) snd_uint12=(mid_uint8%16)+(lst_uint8<<4) return np.concatenate((fst_uint12[:,None],snd_uint12[:,None]),axis=1).flatten()