// Author and Copyright: Johannes Gajdosik, 2007 // License: GPL // g++ -O2 ConvertCatToNative.C -o ConvertCatToNative // If you use a compiler different from gcc - which I discourage - // and want to use mmap star catalogue loading, // you can use this program for converting stellarium star catalogoues // into native format. Your resulting native format catalogue is not // portable, but is has the structs packed in a way that your compiler // understands. And the stellarium binary, that you have build with your // non-gcc compiler, will be able to load it. #include #include #include #include using namespace std; typedef int Int32; typedef unsigned int Uint32; typedef short int Int16; typedef unsigned short int Uint16; #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(1) #endif struct Star1 { // 28 byte int hip:24; // 17 bits needed unsigned char component_ids; // 5 bits needed Int32 x0; // 32 bits needed Int32 x1; // 32 bits needed unsigned char b_v; // 7 bits needed unsigned char mag; // 8 bits needed Uint16 sp_int; // 14 bits needed Int32 dx0,dx1,plx; void repack(bool from_be); void print(void); } #if defined(__GNUC__) __attribute__ ((__packed__)) #endif ; #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(0) #endif #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(1) #endif struct Star2 { // 10 byte int x0:20; int x1:20; int dx0:14; int dx1:14; unsigned int b_v:7; unsigned int mag:5; void repack(bool from_be); void print(void); } #if defined(__GNUC__) __attribute__ ((__packed__)) #endif ; #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(0) #endif #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(1) #endif struct Star3 { // 6 byte int x0:18; int x1:18; unsigned int b_v:7; unsigned int mag:5; void repack(bool from_be); void print(void); } #if defined(__GNUC__) __attribute__ ((__packed__)) #endif ; #if (defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)) #pragma pack(0) #endif static unsigned int bswap_32(unsigned int val) { return ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); } static int UnpackBits(bool from_be,const char *addr,int bits_begin, const int bits_size) { assert(bits_size <= 32); while (bits_begin >= 8) { bits_begin -= 8; addr++; } const int bits_end = bits_begin + bits_size; int rval; if (from_be) { rval = (int)((( (( (((unsigned int)(unsigned char)(addr[0])) << 8) | ((unsigned int)(unsigned char)(addr[1]))) << 8) | ((unsigned int)(unsigned char)(addr[2]))) << 8) | ((unsigned int)(unsigned char)(addr[3]))); if (bits_end <= 32) { if (bits_begin > 0) rval <<= bits_begin; } else { rval <<= bits_begin; unsigned int rval_lo = (unsigned char)(addr[4]); rval_lo >>= (8-bits_begin); rval |= rval_lo; } if (bits_size < 32) rval >>= (32-bits_size); } else { rval = (int)((( (( (((unsigned int)(unsigned char)(addr[3])) << 8) | ((unsigned int)(unsigned char)(addr[2]))) << 8) | ((unsigned int)(unsigned char)(addr[1]))) << 8) | ((unsigned int)(unsigned char)(addr[0]))); if (bits_end <= 32) { if (bits_end < 32) rval <<= (32-bits_end); if (bits_size < 32) rval >>= (32-bits_size); } else { int rval_hi = addr[4]; rval_hi <<= (64-bits_end); rval_hi >>= (32-bits_size); rval = ((unsigned int)rval) >> bits_begin; rval |= rval_hi; } } return rval; } static unsigned int UnpackUBits(bool from_be,const char *addr,int bits_begin, const int bits_size) { assert(bits_size <= 32); while (bits_begin >= 8) { bits_begin -= 8; addr++; } const int bits_end = bits_begin + bits_size; unsigned int rval; if (from_be) { rval = (( (( (((unsigned int)(unsigned char)(addr[0])) << 8) | ((unsigned int)(unsigned char)(addr[1]))) << 8) | ((unsigned int)(unsigned char)(addr[2]))) << 8) | ((unsigned int)(unsigned char)(addr[3])); if (bits_end <= 32) { if (bits_begin > 0) rval <<= bits_begin; } else { rval <<= bits_begin; unsigned int rval_lo = (unsigned char)(addr[4]); rval_lo >>= (8-bits_begin); rval |= rval_lo; } if (bits_size < 32) rval >>= (32-bits_size); } else { rval = (( (( (((unsigned int)(unsigned char)(addr[3])) << 8) | ((unsigned int)(unsigned char)(addr[2]))) << 8) | ((unsigned int)(unsigned char)(addr[1]))) << 8) | ((unsigned int)(unsigned char)(addr[0])); if (bits_end <= 32) { if (bits_begin > 0) rval >>= bits_begin; } else { unsigned int rval_hi = (unsigned char)(addr[4]); rval_hi <<= (32-bits_begin); rval = rval >> bits_begin; rval |= rval_hi; } if (bits_size < 32) rval &= ((((unsigned int)1)< void Convert(FILE *f_in,FILE *f_out,bool from_be,unsigned int nr_of_stars) { for (;nr_of_stars>0;nr_of_stars--) { Star s; if (sizeof(Star) != fread(&s,1,sizeof(Star),f_in)) { printf("Convert: read failed\n"); exit(-1); } s.repack(from_be); if (sizeof(Star) != fwrite(&s,1,sizeof(Star),f_out)) { printf("Convert: write failed\n"); exit(-1); } } } static inline int ReadInt(FILE *f,unsigned int &x) { const int rval = (4 == fread(&x,1,4,f)) ? 0 : -1; return rval; } static void WriteInt(FILE *f,int x) { if (4!=fwrite(&x,1,4,f)) { printf("WriteInt: fwrite failed\n"); exit(-1); } } static void PerformConversion(const char *fname_in,const char *fname_out) { FILE *f_in = fopen(fname_in,"rb"); FILE *f_out = fopen(fname_out,"wb"); if (f_in == 0) { fprintf(stderr,"fopen(%s) failed\n",fname_in); return; } if (f_out == 0) { fprintf(stderr,"fopen(%s) failed\n",fname_out); return; } printf("Reading %s: ",fname_in); unsigned int magic,major,minor,type,level,mag_min,mag_range,mag_steps; if (ReadInt(f_in,magic) < 0 || ReadInt(f_in,type) < 0 || ReadInt(f_in,major) < 0 || ReadInt(f_in,minor) < 0 || ReadInt(f_in,level) < 0 || ReadInt(f_in,mag_min) < 0 || ReadInt(f_in,mag_range) < 0 || ReadInt(f_in,mag_steps) < 0) { printf("bad file\n"); return; } const bool byte_swap = (magic == FILE_MAGIC_OTHER_ENDIAN); if (byte_swap) { // ok, FILE_MAGIC_OTHER_ENDIAN, must swap printf("byteswap "); type = bswap_32(type); major = bswap_32(major); minor = bswap_32(minor); level = bswap_32(level); mag_min = bswap_32(mag_min); mag_range = bswap_32(mag_range); mag_steps = bswap_32(mag_steps); } else if (magic == FILE_MAGIC) { // ok, FILE_MAGIC } else { printf("no .cat or .bcat star catalogue file\n"); return; } const bool from_be = #ifdef WORDS_BIGENDIAN // need for byte_swap on a BE machine means that catalog is LE !byte_swap #else // need for byte_swap on a LE machine means that catalog is BE byte_swap #endif ; printf("type: %u major: %u minor: %u level: %u" " mag_min: %d mag_range: %u mag_steps: %u; ", type,major,minor,level,(int)mag_min,mag_range,mag_steps); if (major > MAX_MAJOR_FILE_VERSION) { printf("unsupported version\n"); return; } WriteInt(f_out,FILE_MAGIC_NATIVE); WriteInt(f_out,type); WriteInt(f_out,major); WriteInt(f_out,minor); WriteInt(f_out,level); WriteInt(f_out,mag_min); WriteInt(f_out,mag_range); WriteInt(f_out,mag_steps); const unsigned int nr_of_zones = (20<<(level<<1)); // 20*4^level unsigned int nr_of_stars = 0; for (unsigned int i=0;i(f_in,f_out,from_be,nr_of_stars); break; case 1: assert(sizeof(Star2) == 10); Convert(f_in,f_out,from_be,nr_of_stars); break; case 2: assert(sizeof(Star3) == 6); Convert(f_in,f_out,from_be,nr_of_stars); break; } fclose(f_out); fclose(f_in); printf("conversion successful\n"); } int main(int argc,char *argv[]) { if (argc != 3) { printf("Usage: %s input_catalogue_file output_catalogue_file\n",argv[0]); return 1; } PerformConversion(argv[1],argv[2]); return 0; }