Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Convert an int to a byte array

constantine-vassilev
4,886 Views

Does Intel has a fast routine for converting a 4 byteint and 4 byte float to a 4 byte byte array
and back?

Thanks in advance,
Constantine

0 Kudos
21 Replies
Rob_Ottenhoff
New Contributor I
4,686 Views
Quoting - thstart

Does Intel has a fast routine for converting a 4 byteint and 4 byte float to a 4 byte byte array
and back?

Thanks in advance,
Constantine

Hi Constantine,

I'm probably missing something, but why not use the old fashioned memcpy ? E.g. :

int i = 0x12345678;
BYTE B[4];
memcpy(B, &i, 4);

Regards,

Rob

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views
I would say there are cases when no conversion is required. For example,
int a;
unsigned char* p = &a;
now you can access a[0], a[1], a[2] and a[3] as a bytes. Be careful though to not change bytes on stack outside of this integer variable.
Vladimir

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik
I would say there are cases when no conversion is required. For example,
int a;
unsigned char* p = &a;
now you can access a[0], a[1], a[2] and a[3] as a bytes. Be careful though to not change bytes on stack outside of this integer variable.
Vladimir


The reason I need this is thatI am creating buffered in memoryLZO compression which to be flushed to disk when needed. To do that I have to store the length of the uncompressed source
and also the length of compressed source.

Here is the problem. ippsEncodeLZO_8u uses byte array to store the compressed information.
I know the source length in advance, ippsEncodeLZO_8u returns destination (compressed)
length which has to be stored in the beginning of the byte array so the decompression to be able
to work later: ippsDecodeLZO_8u. EncodeLZO and DecodeLZO need these 2 lengths as Ipp32utypes - e.g. 4 bytes.

What follows I need to store in beginning of the buffertwo Ipp32u valuesof 4 bytes each and be able to read them later as Ipp32u. The difficulties I see is there is not easy way to save these Ipp32u values as 4 separate bytes as is andread them back directly as Ipp32u. I wroteBig Endian Split routine for splitting the Ipp32u to 4 separate bytes and then again use Big Endian Unsplit routine to read and interpret them back as Ipp32u.

But this adds additional compexyty. What I need is to be able to write and read directly in Ipp32u.
For example writing to file this is possible:

Ipp32u srcLen;


size=


size=

sizeof(srcLen);
fwrite(&srcLen, 1, size, pOutBin);

As you see you can save Ipp32u value directly to the file which is actually a byte array.

You can read this value back later as Ipp32u directly.

Ipp32u srcLen;
size=sizeof(srcLen);
fread(&srcLen, 1, size, pIn);

Best,

Constantine

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views
Depending on your target machine, if it is little-endian (like Intel architecture) and you want to keep multi-byte values in big-endian format you have to have byte swapping. If you can keep values in little-endian format youdo not have todo byte swapping.
By the way, there is ippsByteSwap function in IPP
Vladimir

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik
Depending on your target machine, if it is little-endian (like Intel architecture) and you want to keep multi-byte values in big-endian format you have to have byte swapping. If you can keep values in little-endian format youdo not have todo byte swapping.
By the way, there is ippsByteSwap function in IPP
Vladimir


So - the bottom line - how is the best way to write/read

Ipp32u type as a byte array on Intel machines?

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views
Again, depends on how that 4-byte variable is stored. If it is stored in big-endian format you have to byte swapping. You may call fread first to get 4 bytes and then swap them in little endian format. You also may call fread for each byte separately and progressively construct your little-endian value. In any case, usually it is only needed at some header parse code which rarely takes more than 5% of the whole decoding time in codecs (does not really matter what codecs, this is consistant for JPEG, MPEG, H.264 and so on). Do you think it is time critical part of LZO compression?
Vladimir

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik
Again, depends on how that 4-byte variable is stored. If it is stored in big-endian format you have to byte swapping. You may call fread first to get 4 bytes and then swap them in little endian format. You also may call fread for each byte separately and progressively construct your little-endian value. In any case, usually it is only needed at some header parse code which rarely takes more than 5% of the whole decoding time in codecs (does not really matter what codecs, this is consistant for JPEG, MPEG, H.264 and so on). Do you think it is time critical part of LZO compression?
Vladimir


fread and fwrite is disk related. With fread and fwrite I can specify howto interpret these 4 bytes. In my case I interpret them as Ipp32u, but really they are saved as 4 bytes.I want to do the same in the memory.

e.g. the variable is Ipp32u = 4 bytes. The question is how to store these 4 bytes in Ipp8u
memory array, so to be able to readthese 4 byteslater directly as Ipp32u variable.
This Ipp8u memory array can be saved as a binary file and the first 4 bytes read later
with fread as an Ipp32u variable.

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views

With fread you can't specify to read 4-bytes varaible as big-endian or little-endian value. So you have to think on arhitecture you are running on and on format of the data you read (and how to interpret them) by yourself.

Vladimir

0 Kudos
Sergey_K_Intel
Employee
4,686 Views
Quoting - thstart

What follows I need to store in beginning of the buffertwo Ipp32u valuesof 4 bytes each and be able to read them later as Ipp32u.

Constantine, there are so many ways to implement this... Below is an example with "unsigned int". The same will be with Ipp32u.

unsigned char buffer[1000];
unsigned int *size1 = (unsigned int*)buffer;
unsigned int *size2 = (unsigned int*)(buffer+sizeof(unsigned int));
*size1 = 100;
*size2 = 200;
unsigned char *myStorage=buffer+2*sizeof(unsigned int);
unsigned int myLength = (unsigned int)(sizeof(buffer)-(myStorage-buffer));


You can use memcpy:
unsigned int size1 = 100;
unsigned int size2 = 200;
memcpy(buffer, &size1, sizeof(unsigned int));
memcpy(buffer+sizeof(unsigned int), &size2, sizeof(unsigned int));


Exotic:
union {
unsigned char buffer[1000];
struct {
unsigned int _size1;
unsigned int _size2;
} sizes;
} myStruct;
myStruct.sizes._size1 = 100;
myStruct.sizes._size2 = 200;
unsigned char *myStorage=myStruct.buffer+2*sizeof(unsigned int);
unsigned int myLength = (unsigned int)(sizeof(myStruct.buffer)-sizeof(myStruct.sizes));

You can use structures with sizes at structure head instead of plain buffer. So, many and many :)

Regards,
Sergey

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik

With fread you can't specify to read 4-bytes varaible as big-endian or little-endian value. So you have to think on arhitecture you are running on and on format of the data you read (and how to interpret them) by yourself.

Vladimir


The point is not to be little-endian or big-endian. I am using Intel architecture and want it as simple as possible.

0 Kudos
constantine-vassilev
4,686 Views
Quoting - sergey_kh

Constantine, there are so many ways to implement this... Below is an example with "unsigned int". The same will be with Ipp32u.

unsigned char buffer[1000];
unsigned int *size1 = (unsigned int*)buffer;
unsigned int *size2 = (unsigned int*)(buffer+sizeof(unsigned int));
*size1 = 100;
*size2 = 200;
unsigned char *myStorage=buffer+2*sizeof(unsigned int);
unsigned int myLength = (unsigned int)(sizeof(buffer)-(myStorage-buffer));


You can use memcpy:
unsigned int size1 = 100;
unsigned int size2 = 200;
memcpy(buffer, &size1, sizeof(unsigned int));
memcpy(buffer+sizeof(unsigned int), &size2, sizeof(unsigned int));


Exotic:
union {
unsigned char buffer[1000];
struct {
unsigned int _size1;
unsigned int _size2;
} sizes;
} myStruct;
myStruct.sizes._size1 = 100;
myStruct.sizes._size2 = 200;
unsigned char *myStorage=myStruct.buffer+2*sizeof(unsigned int);
unsigned int myLength = (unsigned int)(sizeof(myStruct.buffer)-sizeof(myStruct.sizes));

You can use structures with sizes at structure head instead of plain buffer. So, many and many :)

Regards,
Sergey

Thanks for the example. The whole point of my question was how easily can READ back the values of Ipp32u
variable, without intermediate routine. I know there many ways to store the information in memory bytewise, the question is how easily to get it back directly. Because in my application compression is made 1 time, but decopression is made thousand times and each conversion takes time. Microsoft has BitConverter doing this but it is for .NET. the question was does Intel has more efficient procedure for the low level C.

Here is a code in C#:

byte[] bytes = { 0, 0, 0, 25 };
int i = BitConverter.ToInt32(bytes, 0);

As you see the storage is in byte array, but the BitConverter gets 4 bytes, combines them and returns
integer.

Now the question is how to do that most efficiently in Standard C.

Thanks in advance,

Konstantin

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views
Are you looking for routine like this?
char a, b, c, d;
int abcd;
abcd = (a << 24) | (b << 16) | (c << 8) | d
or
(d << 24) | (c << 16) | (b << 8) | a
if you need value in different endianess, (I remember youare not consider this as a question of endianess, but actually it is, might be not explicitely)
Vladimir

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik
Are you looking for routine like this?
char a, b, c, d;
int abcd;
abcd = (a << 24) | (b << 16) | (c << 8) | d
or
(d << 24) | (c << 16) | (b << 8) | a
if you need value in different endianess, (I remember youare not consider this as a question of endianess, but actually it is, might be not explicitely)
Vladimir


I suppose this is in the right direction, how to apply this routine to byte array? Endianness is not a question, it does not matter.

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views

simple loop might help I believe.

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik

simple loop might help I believe.


Does Intel has more efficient way of performing Array left shift for example? E.g. having an array(vector) to perform << on entire vector? This is more efficient than a loop.

0 Kudos
Vladimir_Dudnik
Employee
4,686 Views
How do you estimated efficiency? You probably had try such a shift already? Then you may just continue to use it because of higher efficiency.

0 Kudos
constantine-vassilev
4,686 Views
Quoting - vdudnik
How do you estimated efficiency? You probably had try such a shift already? Then you may just continue to use it because of higher efficiency.


By efficiency I mean coding efficiency. Codingloops is not a solution, it is much simpler andefficient to code it asthe Intel IPPvector functions do. If there are vector left shift finction for example LeftShift(Src,Dst), I will get all Src vector elements left shifted with just one command.

By the way I am reading Fixed-Accuracy
Arithmetic Functions Chapter 12 of Intel IPP Signal Processing. 32f is by definition floating point, how they are intepreted as fixed point in Fixed-Accuracy Arithmetic Functions?

0 Kudos
Sergey_K_Intel
Employee
4,686 Views
Quoting - thstart

Because in my application compression is made 1 time, but decopression is made thousand times and each conversion takes time.

You may use any of conversion methods, looking only at method's esthetics. This conversion's burden - comparing to compression/decompression times - anyway will be negligible.

0 Kudos
constantine-vassilev
4,686 Views
>Are you looking for routine like this?
>char a, b, c, d;
>int abcd;
>abcd = (a << 24) | (b << 16) | (c << 8) | d
>or
(d << 24) | (c << 16) | (b << 8) | a
I need the following:
int abcd=1234;
char arr[4];
how the digit 1 from abcd to go to arr[0], the digit 2 to go to arr[1], the digit 3 to go to arr[2] and the digit4 to arr[3].
0 Kudos
constantine-vassilev
4,164 Views
Quoting - thstart
>Are you looking for routine like this?
>char a, b, c, d;
>int abcd;
>abcd = (a << 24) | (b << 16) | (c << 8) | d
>or
(d << 24) | (c << 16) | (b << 8) | a
I need the following:
int abcd=1234;
char arr[4];
how the digit 1 from abcd to go to arr[0], the digit 2 to go to arr[1], the digit 3 to go to arr[2] and the digit4 to arr[3].


Correction:

Ipp32u abcd = 1234;
Ipp8u arr[4];

0 Kudos
Reply