main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <iostream>
#define FITS_BLOCK_SIZE 2880
#define FITS_RECORD_SIZE 80
//ファイル名をコピーして、拡張子 raw を fts に変換します。
void RawNmae2Fts(char *Fts, char *Raw){
strcpy(Fts, Raw);
int len=strlen(Fts);
strcpy(Fts+len-3,"fts");
}
//コピーもとのメモリから格納先メモリに保存します。
//packされた10bit,12bitは16bitに展開してします。
void CnvertImage(unsigned char *dst, unsigned char *src, int srcSize, int bpp){
int j = 0;
switch(bpp){
case 8:
case 16:
for(int i = 0; i < srcSize; i++){
dst[i] = src[i];
}
break;
case 10:
for(int i = 0; i < srcSize; i+=5){
dst[j++] = src[i] * 4 + (src[i+4] ) % 4;
dst[j++] = src[i] / 64;
dst[j++] = src[i+1] * 4 + (src[i+4] >> 2) % 4;
dst[j++] = src[i+1] / 64;
dst[j++] = src[i+2] * 4 + (src[i+4] >> 4 ) % 4;
dst[j++] = src[i+2] / 64;
dst[j++] = src[i+3] * 4 + (src[i+4] >> 6 ) % 4;
dst[j++] = src[i+3] / 64;
}
break;
case 12:
for(int i = 0; i < srcSize; i+=3){
dst[j++] = src[i] * 16 + (src[i+2] ) % 16;
dst[j++] = src[i] / 16;
dst[j++] = src[i+1] * 16 + (src[i+2] >> 4) % 16;
dst[j++] = src[i+1] / 16;
}
break;
default:
break;
}
}
void EndianChange(unsigned char *dst, unsigned char *src, int srcSize, int bpp){
switch(bpp){
case 16:
case 10:
case 12:
for(int i = 0; i < srcSize; i+=2){
dst[i] = src[srcSize-i];
}
break;
case 8:
default:
break;
}
}
int main(int argc, char *argv[]){
if(argc < 4){
printf("usage:%s Width Height RawFilename\n",argv[0]);
exit(EXIT_FAILURE);
}
short width, height;
char *RawFilename;
char FtsFilename[256];
struct stat RawFileInfo;
width = atoi(argv[1]);
height = atoi(argv[2]);
RawFilename = argv[3];
RawNmae2Fts(FtsFilename, RawFilename);
if (stat(RawFilename, &RawFileInfo) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
int BinSize, FtsSize;
int RawSize = RawFileInfo.st_size;
int bpp = RawSize * 8 / width / height;
//変換後のサイズを計算
if(bpp == 10){
BinSize = RawSize * 2 * 4 / 5; // 8,8,8,8,(2,2,2,2)
}else if(bpp == 12){
BinSize = RawSize * 2 * 2 / 3; // 8,8,(4,4)
}else{
BinSize = RawSize;
}
if(BinSize % FITS_BLOCK_SIZE > 0)
FtsSize = BinSize / FITS_BLOCK_SIZE + 1;
else
FtsSize = BinSize / FITS_BLOCK_SIZE;
FtsSize = FtsSize * FITS_BLOCK_SIZE;
printf("depth:%dbit\n", bpp);
printf("Raw %s %d bytes\n",RawFilename, RawSize);
printf("Fts %s %d bytes\n",FtsFilename, FtsSize + FITS_BLOCK_SIZE);
unsigned char *RawImage = (unsigned char *)malloc(RawSize);
unsigned char *BinImage = (unsigned char *)malloc(BinSize);
unsigned char *FtsImage = (unsigned char *)malloc(FtsSize);
char *FtsHeader = (char *)malloc(FITS_BLOCK_SIZE);
if(RawImage == NULL){
perror("Raw malloc");
exit(EXIT_FAILURE);
}
if(FtsImage == NULL){
perror("Fts malloc");
exit(EXIT_FAILURE);
}
FILE *fpRaw,*fpFts;
fpRaw = fopen(RawFilename, "rb");
int r = fread(RawImage, sizeof(char), RawSize, fpRaw);
printf("Read %d bytes\n", r);
fclose(fpRaw);
CnvertImage(FtsImage, RawImage, RawSize, bpp);
EndianChange(FtsImage, BinImage, BinSize, bpp);
int offset = 0;
sprintf(FtsHeader+offset,"%-80s", "SIMPLE = T / Created by raw2fts");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"BITPIX = %19d / %-49s", 16, "number of bits per data pixel");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"NAXIS = %19d / %-49s", 2, "number of data axes");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"NAXIS1 = %19d / %-49s", width, "length of data axis 1");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"NAXIS2 = %19d / %-49s", height, "length of data axis 2");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"BZERO = %19d / %-49s", 0, "data range offset");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"BSCALE = %19d / %-49s", 1, "lscaling factor");
offset += FITS_RECORD_SIZE;
sprintf(FtsHeader+offset,"%-80s", "END");
for(int i=0; i < FITS_BLOCK_SIZE; i++){
if(*(FtsHeader+i) == 0x00)
*(FtsHeader+i) = 0x20;
}
int w;
fpFts = fopen(FtsFilename, "wb");
w = fwrite(FtsHeader, sizeof(char), FITS_BLOCK_SIZE, fpFts);
printf("%ld ", FITS_BLOCK_SIZE * sizeof(char));
w = fwrite(FtsImage, sizeof(char), FtsSize, fpFts);
printf("+ %d bytes\n", w);
fclose(fpFts);
free(FtsHeader);
free(FtsImage);
free(BinImage);
free(RawImage);
}