Convert NSData to primitive variable with ieee-754 or twos-complement ?
Posted
by William GILLARD
on Stack Overflow
See other posts from Stack Overflow
or by William GILLARD
Published on 2010-06-11T20:44:33Z
Indexed on
2010/06/11
21:12 UTC
Read the original article
Hit count: 578
Hi every one.
I am new programmer in Obj-C and cocoa. Im a trying to write a framework which will be used to read a binary files (Flexible Image Transport System or FITS binary files, usually used by astronomers). The binary data, that I am interested to extract, can have various formats and I get its properties by reading the header of the FITS file.
Up to now, I manage to create a class to store the content of the FITS file and to isolate the header into a NSString
object and the binary data into a NSData
object. I also manage to write method which allow me to extract the key values from the header that are very valuable to interpret the binary data.
I am now trying to convert the NSData
object into a primitive array (array of double
, int
, short
...). But, here, I get stuck and would appreciate any help.
According to the documentation I have about the FITS file, I have 5 possibilities to interpret the binary data depending on the value of the BITPIX
key:
BITPIX value | Data represented
8 | Char or unsigned binary int
16 | 16-bit two's complement binary integer
32 | 32-bit two's complement binary integer
64 | 64-bit two's complement binary integer
-32 | IEEE single precision floating-point
-64 | IEEE double precision floating-point
I already write the peace of code, shown bellow, to try to convert the NSData
into a primitive array.
// self reefer to my FITS class which contain a NSString object
// with the content of the header and a NSData object with the binary data.
-(void*) GetArray
{
switch (BITPIX)
{
case 8:
return [self GetArrayOfUInt];
break;
case 16:
return [self GetArrayOfInt];
break;
case 32:
return [self GetArrayOfLongInt];
break;
case 64:
return [self GetArrayOfLongLong];
break;
case -32:
return [self GetArrayOfFloat];
break;
case -64:
return [self GetArrayOfDouble];
break;
default:
return NULL;
}
}
// then I show you the method to convert the NSData into a primitive array.
// I restrict my example to the case of 'double'. Code is similar for other methods
// just change double by 'unsigned int' (BITPIX 8), 'short' (BITPIX 16)
// 'int' (BITPIX 32) 'long lon' (BITPIX 64), 'float' (BITPIX -32).
-(double*) GetArrayOfDouble
{
int Nelements=[self NPIXEL]; // Metod to extract, from the header
// the number of element into the array
NSLog(@"TOTAL NUMBER OF ELEMENTS [%i]\n",Nelements);
//CREATE THE ARRAY
double (*array)[Nelements];
// Get the total number of bits in the binary data
int Nbit = abs(BITPIX)*GCOUNT*(PCOUNT + Nelements); // GCOUNT and PCOUNT are defined
// into the header
NSLog(@"TOTAL NUMBER OF BIT [%i]\n",Nbit);
int i=0;
//FILL THE ARRAY
double Value;
for(int bit=0; bit < Nbit; bit+=sizeof(double))
{
[Img getBytes:&Value range:NSMakeRange(bit,sizeof(double))];
NSLog(@"[%i]:(%u)%.8G\n",i,bit,Value);
(*array)[i]=Value;
i++;
}
return (*array);
}
However, the value I print in the loop are very different from the expected values (compared using official FITS software). Therefore, I think that the Obj-C double
does not use the IEEE-754 convention as well as the Obj-C int
are not twos-complement. I am really not familiar with this two convention (IEEE and twos-complement) and would like to know how I can do this conversion with Obj-C.
In advance many thanks for any help or information.
© Stack Overflow or respective owner