7
$\begingroup$

during the import of a complex file format I handle ByteArray or lists of byte values. While I can easy transform them from one type to each other:

ba=ByteArray[{1,2,3,4,5,6}];
Normal[ba]

I have problems taking specific bytes of my list and converting them according a given number format e.g. Integer8, Integer32 or Real32.

Normal@ba[[1;;2]] (*Shall interpretet as Integer16*)
Normal@ba[[3;;6]] (*Shall interpretet as Real32*)

Is there an internal and elegant way to do so?

I wrote a workaround for Integer numbers like below but I would guess an internal solution will be way more efficient ...

ByteToInteger[byteArray_,LSBStart_:True,bitSize_:16,signed_:False] :=
    Module[{i,array=byteArray,value=0}, 

        (*Reverse for LSB*)
        If[LSBStart==False,
           array=Reverse[array];
        ];
        
        array=PadLeft[array,bitSize]

        
        (*calculate Unsigned value*)
        value=array[[1]];
        For[i=2,i<=Length@array,i++,
            value=value+array[[i]]*256^(i-1)
        ];
        
        (*adapt to signed if needed*)
        If[signed==True&&value>=2^(bitSize-1),
            value=-(2^bitSize-(value-2^(bitSize-1)))
        ];
        
        value  
    ]

I am open to any suggestions ...

$\endgroup$

1 Answer 1

6
$\begingroup$

ImportByteArray does what you need:

ba = ByteArray[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}];

ImportByteArray[ba[[1 ;; 4]], "Integer32"]
(*    {67305985}    *)

ImportByteArray[ba[[5 ;; 12]], "UnsignedInteger64"]
(*    {867798387104613893}    *)

Here's a list of availably types for import:

  • "Bit" — individual binary bits (Import, Export only)
  • "Byte" — 8-bit unsigned integer
  • "Integer8", "Integer16", ... — 8-, 16-, 24- 32-, 64-, 128-bit signed integers
  • "UnsignedInteger8", ... — 8-, 16-, 24-, 32-, 64-, 128-bit unsigned integers
  • "Real32", "Real64", "Real128" — IEEE single‐, double‐, quad-precision real numbers
  • "Complex64", "Complex128", "Complex256" — IEEE complex numbers
  • "Character8", "Character16" — 8- and 16-bit (Unicode) characters
  • "TerminatedString" — null-terminated string
$\endgroup$
3
  • $\begingroup$ Yes this does the trick for the real numbers. Thank you very much. Do you know if I shouls LSB and MSB via reversing the array or is there another way to do it? $\endgroup$
    – Tschibi
    Commented May 2, 2021 at 16:07
  • $\begingroup$ You can use the ByteOrdering option, as in ImportByteArray[ba[[1 ;; 8]], "Real64", ByteOrdering -> -1] (or +1, depending on your machine). $\endgroup$
    – Roman
    Commented May 2, 2021 at 16:31
  • $\begingroup$ Ok. Thank you very much. $\endgroup$
    – Tschibi
    Commented May 2, 2021 at 16:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.