mirror of
https://github.com/eddyem/fitsmaniplib.git
synced 2026-01-31 20:35:12 +03:00
Fix some bugs in keyword functions; add stupid image read/write
This commit is contained in:
parent
82b214db95
commit
b8dc08bbfd
@ -94,7 +94,7 @@ link_directories(${${PROJ}_LIBRARY_DIRS})
|
|||||||
add_definitions(-DLOCALEDIR=\"${LOCALEDIR}\"
|
add_definitions(-DLOCALEDIR=\"${LOCALEDIR}\"
|
||||||
-DPACKAGE_VERSION=\"${PROJ_VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
-DPACKAGE_VERSION=\"${PROJ_VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
||||||
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
|
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
|
||||||
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
-DMAJOR_VERSION=\"${MAJOR_VESION}\" -DVERSION=\"${PROJ_VERSION}\")
|
||||||
|
|
||||||
# -l
|
# -l
|
||||||
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES})
|
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES})
|
||||||
|
|||||||
13
FITSmanip.h
13
FITSmanip.h
@ -105,7 +105,9 @@ typedef struct{
|
|||||||
typedef struct{
|
typedef struct{
|
||||||
int width; // width
|
int width; // width
|
||||||
int height; // height
|
int height; // height
|
||||||
int dtype; // picture data type
|
int bitpix; // original bitpix
|
||||||
|
int dtype; // type of stored data
|
||||||
|
int pxsz; // number of bytes for one pixel data
|
||||||
void *data; // picture data
|
void *data; // picture data
|
||||||
} FITSimage;
|
} FITSimage;
|
||||||
|
|
||||||
@ -153,7 +155,7 @@ typedef enum{
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void keylist_free(KeyList **list);
|
void keylist_free(KeyList **list);
|
||||||
KeyList *keylist_add_record(KeyList **list, char *rec);
|
KeyList *keylist_add_record(KeyList **list, char *rec, int check);
|
||||||
KeyList *keylist_find_key(KeyList *list, char *key);
|
KeyList *keylist_find_key(KeyList *list, char *key);
|
||||||
void keylist_remove_key(KeyList **list, char *key);
|
void keylist_remove_key(KeyList **list, char *key);
|
||||||
KeyList *keylist_modify_key(KeyList *list, char *key, char *newval);
|
KeyList *keylist_modify_key(KeyList *list, char *key, char *newval);
|
||||||
@ -173,9 +175,9 @@ void table_print_all(FITS *fits);
|
|||||||
|
|
||||||
void image_free(FITSimage **ima);
|
void image_free(FITSimage **ima);
|
||||||
FITSimage *image_read(FITS *fits);
|
FITSimage *image_read(FITS *fits);
|
||||||
#define image_datatype_size(d) (abs(d)/8)
|
int image_datatype_size(int bitpix, int *dtype);
|
||||||
void *image_data_malloc(size_t w, size_t h, int dtype);
|
void *image_data_malloc(size_t w, size_t h, int pxbytes);
|
||||||
FITSimage *image_new(size_t w, size_t h, int dtype);
|
FITSimage *image_new(size_t w, size_t h, int bitpix);
|
||||||
FITSimage *image_mksimilar(FITSimage *in);
|
FITSimage *image_mksimilar(FITSimage *in);
|
||||||
FITSimage *image_copy(FITSimage *in);
|
FITSimage *image_copy(FITSimage *in);
|
||||||
//FITSimage *image_build(size_t h, size_t w, int dtype, uint8_t *indata);
|
//FITSimage *image_build(size_t h, size_t w, int dtype, uint8_t *indata);
|
||||||
@ -184,6 +186,7 @@ void FITS_free(FITS **fits);
|
|||||||
FITS *FITS_read(char *filename);
|
FITS *FITS_read(char *filename);
|
||||||
FITS *FITS_open(char *filename);
|
FITS *FITS_open(char *filename);
|
||||||
bool FITS_write(char *filename, FITS *fits);
|
bool FITS_write(char *filename, FITS *fits);
|
||||||
|
bool FITS_rewrite(FITS *fits);
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* fileops.c *
|
* fileops.c *
|
||||||
|
|||||||
@ -16,6 +16,12 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This example allows to list all keywords in given FITS-file, list amount and types of HDUs in file,
|
||||||
|
add new keywords, modify old keywords.
|
||||||
|
New data could be saved to new file or in place into opened file.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -24,6 +30,8 @@ typedef struct{
|
|||||||
int list; // print keyword list
|
int list; // print keyword list
|
||||||
int contents; // print short description of file contents
|
int contents; // print short description of file contents
|
||||||
char **addrec; // add some records to keywords in first HDU
|
char **addrec; // add some records to keywords in first HDU
|
||||||
|
char *outfile; // output file name
|
||||||
|
char **modify; // keys which values should be modified
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -43,7 +51,9 @@ myoption cmdlnopts[] = {
|
|||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
||||||
{"contents",NO_ARGS, NULL, 'c', arg_none, APTR(&G.contents), _("show short file contents")},
|
{"contents",NO_ARGS, NULL, 'c', arg_none, APTR(&G.contents), _("show short file contents")},
|
||||||
{"list", NO_ARGS, NULL, 'l', arg_none, APTR(&G.list), _("list all keywords")},
|
{"list", NO_ARGS, NULL, 'l', arg_none, APTR(&G.list), _("list all keywords")},
|
||||||
{"addrec", MULT_PAR, NULL, 'a', arg_string, APTR(&G.addrec), _("add record to file (you can add more than one record in once, point more -a)")},
|
{"addrec", MULT_PAR, NULL, 'a', arg_string, APTR(&G.addrec), _("add record to first HDU (you can add more than one record in once, point more -a)")},
|
||||||
|
{"output", NEED_ARG, NULL, 'o', arg_string, APTR(&G.outfile), _("save result to file (else save to same file)")},
|
||||||
|
{"modify", MULT_PAR, NULL, 'm', arg_string, APTR(&G.modify), _("modify values values of given keys (each param should be \"key = new_value\")")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,7 +96,7 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
if(G.contents){
|
if(G.contents){
|
||||||
green("\n\nFile consists of %d HDUs:\n", N);
|
green("\n\nFile consists of %d HDUs:\n", N);
|
||||||
for(int i = 0; i <= N; ++i){
|
for(int i = 1; i <= N; ++i){
|
||||||
printf("\tHDU #%d - ", i);
|
printf("\tHDU #%d - ", i);
|
||||||
switch(f->HDUs[i].hdutype){
|
switch(f->HDUs[i].hdutype){
|
||||||
case IMAGE_HDU:
|
case IMAGE_HDU:
|
||||||
@ -108,9 +118,30 @@ int main(int argc, char *argv[]){
|
|||||||
char **ptr = G.addrec;
|
char **ptr = G.addrec;
|
||||||
while(*ptr){
|
while(*ptr){
|
||||||
printf("record: %s\n", *ptr);
|
printf("record: %s\n", *ptr);
|
||||||
|
keylist_add_record(&(f->HDUs[1].keylist), *ptr++, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(G.modify){
|
||||||
|
char **ptr = G.modify;
|
||||||
|
while(*ptr){
|
||||||
|
printf("modify: %s\n", *ptr);
|
||||||
|
char *val = strchr(*ptr, '=');
|
||||||
|
if(!val){
|
||||||
|
WARNX("should be: 'parameter = value / comment'");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*val++ = 0; // now `val` is value + comment; ptr is key
|
||||||
|
if(!keylist_modify_key(f->HDUs[1].keylist, *ptr, val)){
|
||||||
|
WARNX("key %s not found", *ptr);
|
||||||
|
}
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(G.outfile){ // save result to new file
|
||||||
|
FITS_write(G.outfile, f);
|
||||||
|
}else{
|
||||||
|
FITS_rewrite(f);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
248
fits.c
248
fits.c
@ -24,6 +24,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
@ -59,16 +60,29 @@ KeyList *keylist_get_end(KeyList *list){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief keylist_add_record - add record to keylist
|
* @brief keylist_add_record - add record to keylist with optional check
|
||||||
* @param list (io) - pointer to root of list or NULL
|
* @param list (io) - pointer to root of list or NULL
|
||||||
* if *root == NULL, created node will be placed there
|
* if *root == NULL, created node will be placed there
|
||||||
* @param rec (i) - data inserted
|
* @param rec (i) - data inserted
|
||||||
* @return pointer to created node
|
* @param check - !=0 to check `rec` with fits_parse_template
|
||||||
|
* @return pointer to created node (if list == NULL - don't add created record to any list)
|
||||||
*/
|
*/
|
||||||
KeyList *keylist_add_record(KeyList **list, char *rec){
|
KeyList *keylist_add_record(KeyList **list, char *rec, int check){
|
||||||
|
if(!rec) return NULL;
|
||||||
KeyList *node, *last;
|
KeyList *node, *last;
|
||||||
if((node = (KeyList*) MALLOC(KeyList, 1)) == 0) return NULL; // allocation error
|
if((node = (KeyList*) MALLOC(KeyList, 1)) == 0) return NULL; // allocation error
|
||||||
node->record = strdup(rec); // insert data
|
int tp = 0, st = 0;
|
||||||
|
if(check){
|
||||||
|
char card[FLEN_CARD];
|
||||||
|
fits_parse_template(rec, card, &tp, &st);
|
||||||
|
if(st){
|
||||||
|
fits_report_error(stderr, st);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG("\n WAS: %s\nBECOME: %s\ntp=%d", rec, card, tp);
|
||||||
|
rec = card;
|
||||||
|
}
|
||||||
|
node->record = strdup(rec);
|
||||||
if(!node->record){
|
if(!node->record){
|
||||||
/// "îÅ ÍÏÇÕ ÓËÏÐÉÒÏ×ÁÔØ ÄÁÎÎÙÅ"
|
/// "îÅ ÍÏÇÕ ÓËÏÐÉÒÏ×ÁÔØ ÄÁÎÎÙÅ"
|
||||||
WARNX(_("Can't copy data"));
|
WARNX(_("Can't copy data"));
|
||||||
@ -95,14 +109,17 @@ KeyList *keylist_add_record(KeyList **list, char *rec){
|
|||||||
KeyList *keylist_find_key(KeyList *list, char *key){
|
KeyList *keylist_find_key(KeyList *list, char *key){
|
||||||
if(!list || !key) return NULL;
|
if(!list || !key) return NULL;
|
||||||
size_t L = strlen(key);
|
size_t L = strlen(key);
|
||||||
|
DBG("try to find %s", key);
|
||||||
do{
|
do{
|
||||||
if(list->record){
|
if(list->record){
|
||||||
if(strncmp(list->record, key, L) == 0){ // key found
|
if(strncasecmp(list->record, key, L) == 0){ // key found
|
||||||
|
DBG("found:\n%s", list->record);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}while(list);
|
}while(list);
|
||||||
|
DBG("not found");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,13 +132,17 @@ KeyList *keylist_find_key(KeyList *list, char *key){
|
|||||||
*/
|
*/
|
||||||
KeyList *keylist_modify_key(KeyList *list, char *key, char *newval){
|
KeyList *keylist_modify_key(KeyList *list, char *key, char *newval){
|
||||||
// TODO: look modhead.c in cexamples for protected keys
|
// TODO: look modhead.c in cexamples for protected keys
|
||||||
char buf[FLEN_CARD];
|
char buf[FLEN_CARD], test[2*FLEN_CARD];
|
||||||
KeyList *rec = keylist_find_key(list, key);
|
KeyList *rec = keylist_find_key(list, key);
|
||||||
if(!rec) return NULL;
|
if(!rec) return NULL;
|
||||||
char *comm = strchr(rec->record, '/');
|
snprintf(test, 2*FLEN_CARD, "%s = %s", key, newval);
|
||||||
if(!comm) comm = "";
|
int tp, st = 0;
|
||||||
// TODO: use fits_parse_template
|
fits_parse_template(test, buf, &tp, &st);
|
||||||
snprintf(buf, FLEN_CARD, "%-8s=%21s %s", key, newval, comm);
|
if(st){
|
||||||
|
fits_report_error(stderr, st);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DBG("new record:\n%s", buf);
|
||||||
FREE(rec->record);
|
FREE(rec->record);
|
||||||
rec->record = strdup(buf);
|
rec->record = strdup(buf);
|
||||||
return rec;
|
return rec;
|
||||||
@ -222,7 +243,7 @@ KeyList *keylist_copy(KeyList *list){
|
|||||||
int n = 0;
|
int n = 0;
|
||||||
#endif
|
#endif
|
||||||
do{
|
do{
|
||||||
keylist_add_record(&newlist, list->record);
|
keylist_add_record(&newlist, list->record, 0);
|
||||||
list = list->next;
|
list = list->next;
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
++n;
|
++n;
|
||||||
@ -269,7 +290,7 @@ KeyList *keylist_read(FITS *fits){
|
|||||||
fits_read_record(fits->fp, j, card, &fst);
|
fits_read_record(fits->fp, j, card, &fst);
|
||||||
if(fst) fits_report_error(stderr, fst);
|
if(fst) fits_report_error(stderr, fst);
|
||||||
else{
|
else{
|
||||||
KeyList *kl = keylist_add_record(&list, card);
|
KeyList *kl = keylist_add_record(&list, card, 0);
|
||||||
if(!kl){
|
if(!kl){
|
||||||
/// "îÅ ÍÏÇÕ ÄÏÂÁ×ÉÔØ ÚÁÐÉÓØ × ÓÐÉÓÏË"
|
/// "îÅ ÍÏÇÕ ÄÏÂÁ×ÉÔØ ÚÁÐÉÓØ × ÓÐÉÓÏË"
|
||||||
WARNX(_("Can't add record to list"));
|
WARNX(_("Can't add record to list"));
|
||||||
@ -767,47 +788,102 @@ returning:
|
|||||||
return fits;
|
return fits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool keylist_write(KeyList *kl, fitsfile *fp){
|
||||||
|
int st = 0;
|
||||||
|
bool ret = TRUE;
|
||||||
|
if(!fp || !kl) return FALSE;
|
||||||
|
while(kl){
|
||||||
|
if(kl->keyclass > TYP_CMPRS_KEY){ // this record should be written
|
||||||
|
fits_write_record(fp, kl->record, &st);
|
||||||
|
DBG("Write %s, st = %d", kl->record, st);
|
||||||
|
if(st){fits_report_error(stderr, st); st = 0; ret = FALSE;}
|
||||||
|
}
|
||||||
|
kl = kl->next;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FITS_write - write FITS file to disk
|
||||||
|
* @param filename - new filename
|
||||||
|
* @param fits - structure to write
|
||||||
|
* @return TRUE if all OK
|
||||||
|
*/
|
||||||
bool FITS_write(char *filename, FITS *fits){
|
bool FITS_write(char *filename, FITS *fits){
|
||||||
if(!filename || !fits) return FALSE;
|
if(!filename || !fits) return FALSE;
|
||||||
/*int w = fits->width, h = fits->height, fst = 0;
|
|
||||||
long naxes[2] = {w, h};
|
|
||||||
size_t sz = w * h;
|
|
||||||
fitsfile *fp;
|
fitsfile *fp;
|
||||||
|
int fst = 0;
|
||||||
fits_create_diskfile(&fp, filename, &fst);
|
fits_create_diskfile(&fp, filename, &fst);
|
||||||
|
DBG("create file %s", filename);
|
||||||
if(fst){fits_report_error(stderr, fst); return FALSE;}
|
if(fst){fits_report_error(stderr, fst); return FALSE;}
|
||||||
// TODO: save FITS files in original (or given by user) data format!
|
int N = fits->NHDUs;
|
||||||
// check fits->dtype - does all data fits it
|
for(int i = 1; i <= N; ++i){
|
||||||
fits_create_img(fp, fits->dtype, 2, naxes, &fst);
|
FITSHDU *hdu = &fits->HDUs[i];
|
||||||
if(fst){fits_report_error(stderr, fst); return FALSE;}
|
if(!hdu) continue;
|
||||||
if(fits->keylist){ // there's keys
|
FITSimage *img;
|
||||||
KeyList *records = fits->keylist;
|
long naxes[2] = {0,0};
|
||||||
while(records){
|
KeyList *records = hdu->keylist;
|
||||||
char *rec = records->record;
|
DBG("HDU #%d (type %d)", i, hdu->hdutype);
|
||||||
records = records->next;
|
switch(hdu->hdutype){
|
||||||
// TODO: check types of headers from each record!
|
case IMAGE_HDU:
|
||||||
if(strncmp(rec, "SIMPLE", 6) == 0 || strncmp(rec, "EXTEND", 6) == 0) // key "file does conform ..."
|
img = hdu->contents.image;
|
||||||
continue;
|
if(!img && records){ // something wrong - just write keylist
|
||||||
// comment of obligatory key in FITS head
|
DBG("create empty image with records");
|
||||||
else if(strncmp(rec, "COMMENT FITS", 14) == 0 || strncmp(rec, "COMMENT and Astrophysics", 26) == 0)
|
fits_create_img(fp, SHORT_IMG, 0, naxes, &fst);
|
||||||
continue;
|
if(fst){fits_report_error(stderr, fst); fst = 0; continue;}
|
||||||
else if(strncmp(rec, "NAXIS", 5) == 0 || strncmp(rec, "BITPIX", 6) == 0) // NAXIS, NAXISxxx, BITPIX
|
keylist_write(records, fp);
|
||||||
continue;
|
DBG("OK");
|
||||||
int ret = fits_write_record(fp, rec, &fst);
|
continue;
|
||||||
if(fst){fits_report_error(stderr, fst);}
|
}
|
||||||
else if(ret) WARNX(_("Can't write record %s"), rec);
|
naxes[0] = img->width, naxes[1] = img->height;
|
||||||
// DBG("write key: %s", rec);
|
DBG("create, bitpix: %d, naxes = {%zd, %zd}", img->bitpix, naxes[0], naxes[1]);
|
||||||
|
//fits_create_img(fp, img->bitpix, 2, naxes, &fst);
|
||||||
|
fits_create_img(fp, SHORT_IMG, 2, naxes, &fst);
|
||||||
|
if(fst){fits_report_error(stderr, fst); fst = 0; continue;}
|
||||||
|
keylist_write(records, fp);
|
||||||
|
DBG("OK, now write image");
|
||||||
|
// TODO: change to original data type according to bitpix or more whide according to min/max
|
||||||
|
DBG("bitpix: %d, dtype: %d", SHORT_IMG, img->dtype);
|
||||||
|
//int bscale = 1, bzero = 32768, status = 0;
|
||||||
|
//fits_set_bscale(fp, bscale, bzero, &status);
|
||||||
|
if(img && img->data){
|
||||||
|
fits_write_img(fp, TUSHORT, 1, img->width * img->height, img->data, &fst);
|
||||||
|
//fits_write_img(fp, img->dtype, 1, img->width * img->height, img->data, &fst);
|
||||||
|
DBG("status: %d", fst);
|
||||||
|
if(fst){fits_report_error(stderr, fst); fst = 0; continue;}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BINARY_TBL:
|
||||||
|
case ASCII_TBL:
|
||||||
|
// TODO: save table
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fits->lasthdu = 1;
|
|
||||||
//FITSFUN(fits_write_record, fp, "COMMENT modified by simple test routine");
|
|
||||||
fits_write_img(fp, TDOUBLE, 1, sz, fits->data, &fst);
|
|
||||||
if(fst){fits_report_error(stderr, fst); return FALSE;}
|
|
||||||
if(fits->tables) table_write(fits, fp);
|
|
||||||
fits_close_file(fp, &fst);
|
fits_close_file(fp, &fst);
|
||||||
if(fst){fits_report_error(stderr, fst);}*/
|
if(fst){fits_report_error(stderr, fst);}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief FITS_rewrite - rewrite file in place
|
||||||
|
* @param fits - pointer to FITS structure
|
||||||
|
* @return TRUE if all OK
|
||||||
|
*/
|
||||||
|
bool FITS_rewrite(FITS *fits){
|
||||||
|
FNAME();
|
||||||
|
char *nm = tmpnam(NULL);
|
||||||
|
if(!nm){WARN("tmpnam()"); return FALSE;}
|
||||||
|
char *fnm = strrchr(nm, '/');
|
||||||
|
if(!fnm){WARN("strrchr()"); return FALSE;}
|
||||||
|
++fnm;
|
||||||
|
DBG("make link: %s -> %s", fits->filename, fnm);
|
||||||
|
if(link(fits->filename, fnm)){
|
||||||
|
WARN("link()");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* FITS images *
|
* FITS images *
|
||||||
@ -819,30 +895,74 @@ void image_free(FITSimage **img){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief image_malloc - allocate memory for given data type
|
* @brief image_datatype_size - calculate size of one data element for given bitpix
|
||||||
* @param w - image width
|
* @param bitpix - value of BITPIX
|
||||||
* @param h - image height
|
* @param dtype (o) - nearest type of data to fit input type
|
||||||
* @param dtype - data type
|
* @return amount of space need to store one pixel data
|
||||||
|
*/
|
||||||
|
int image_datatype_size(int bitpix, int *dtype){
|
||||||
|
int s = bitpix/8;
|
||||||
|
if(dtype){
|
||||||
|
switch(s){
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
*dtype = TINT;
|
||||||
|
s = 4;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*dtype = TLONG;
|
||||||
|
break;
|
||||||
|
case -4:
|
||||||
|
case -8:
|
||||||
|
*dtype = TDOUBLE;
|
||||||
|
s = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0; // wrong bitpix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("bitpix: %d, dtype=%d, imgs=%d", bitpix, *dtype, s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief image_malloc - allocate memory for given bitpix
|
||||||
|
* @param w - image width
|
||||||
|
* @param h - image height
|
||||||
|
* @param pxbytes- amount of bytes to store data from one pixel
|
||||||
* @return allocated memory
|
* @return allocated memory
|
||||||
*/
|
*/
|
||||||
void *image_data_malloc(size_t w, size_t h, int dtype){
|
void *image_data_malloc(size_t w, size_t h, int pxbytes){
|
||||||
void *data = calloc(w*h, image_datatype_size(dtype));
|
if(!pxbytes || !w || !h) return NULL;
|
||||||
|
void *data = calloc(w*h, pxbytes);
|
||||||
|
DBG("Allocate %zd members of size %d", w*h, pxbytes);
|
||||||
if(!data) ERR(_("calloc()"));
|
if(!data) ERR(_("calloc()"));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief image_new - create an empty image without headers, assign data type to "dtype"
|
* @brief image_new - create an empty image without headers, assign BITPIX to "bitpix"
|
||||||
* @param w - image width
|
* @param w - image width
|
||||||
* @param h - image height
|
* @param h - image height
|
||||||
* @param dtype - image data type
|
* @param dtype - image data type
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
FITSimage *image_new(size_t w, size_t h, int dtype){
|
FITSimage *image_new(size_t w, size_t h, int bitpix){
|
||||||
FITSimage *out = MALLOC(FITSimage, 1);
|
FITSimage *out = MALLOC(FITSimage, 1);
|
||||||
out->data = image_data_malloc(w, h, dtype);
|
int dtype, pxsz = image_datatype_size(bitpix, &dtype);
|
||||||
|
if(w && h){
|
||||||
|
out->data = image_data_malloc(w, h, pxsz);
|
||||||
|
if(!out->data){
|
||||||
|
WARNX(_("Bad w, h or pxsz"));
|
||||||
|
FREE(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
out->width = w;
|
out->width = w;
|
||||||
out->height = h;
|
out->height = h;
|
||||||
|
out->pxsz = pxsz;
|
||||||
|
out->bitpix = bitpix;
|
||||||
out->dtype = dtype;
|
out->dtype = dtype;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -907,7 +1027,7 @@ FITSimage *image_build(size_t h, size_t w, int dtype, uint8_t *indata){
|
|||||||
*/
|
*/
|
||||||
FITSimage *image_mksimilar(FITSimage *img){
|
FITSimage *image_mksimilar(FITSimage *img){
|
||||||
if(!img || img->height < 1 || img->width < 1) return NULL;
|
if(!img || img->height < 1 || img->width < 1) return NULL;
|
||||||
return image_new(img->width, img->height, img->dtype);
|
return image_new(img->width, img->height, img->bitpix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -917,7 +1037,7 @@ FITSimage *image_copy(FITSimage *in){
|
|||||||
FITSimage *out = image_mksimilar(in);
|
FITSimage *out = image_mksimilar(in);
|
||||||
if(!out) return NULL;
|
if(!out) return NULL;
|
||||||
// TODO: size of data as in original!
|
// TODO: size of data as in original!
|
||||||
memcpy(out->data, in->data, sizeof(double)*in->width*in->height);
|
memcpy(out->data, in->data, (in->pxsz)*(in->width)*(in->height));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,20 +1049,30 @@ FITSimage *image_copy(FITSimage *in){
|
|||||||
FITSimage *image_read(FITS *fits){
|
FITSimage *image_read(FITS *fits){
|
||||||
// TODO: open not only 2-dimensional files!
|
// TODO: open not only 2-dimensional files!
|
||||||
// get image dimensions
|
// get image dimensions
|
||||||
int naxis, fst = 0, dtype;
|
int naxis, fst = 0, bitpix;
|
||||||
long naxes[2] = {0,0};
|
long naxes[2] = {0,0};
|
||||||
fits_get_img_param(fits->fp, 2, &dtype, &naxis, naxes, &fst);
|
fits_get_img_param(fits->fp, 2, &bitpix, &naxis, naxes, &fst);
|
||||||
if(fst){fits_report_error(stderr, fst); return NULL;}
|
if(fst){fits_report_error(stderr, fst); return NULL;}
|
||||||
if(naxis > 2){
|
if(naxis > 2){
|
||||||
WARNX(_("Images with > 2 dimensions are not supported"));
|
WARNX(_("Images with > 2 dimensions are not supported"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}/*
|
||||||
DBG("got image %ldx%ld pix, bitpix=%d", naxes[0], naxes[1], dtype);
|
if(naxis < 2){
|
||||||
|
WARNX(_("Not an image: NAXIS = %d"), naxis);
|
||||||
|
return NULL;
|
||||||
|
}*/
|
||||||
|
DBG("got image %ldx%ld pix, bitpix=%d", naxes[0], naxes[1], bitpix);
|
||||||
|
|
||||||
FITSimage *img = image_new(naxes[0], naxes[1], dtype);
|
FITSimage *img = image_new(naxes[0], naxes[1], bitpix);
|
||||||
|
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
fits_read_img(fits->fp, dtype, 1, naxes[0]*naxes[1], NULL, img->data, &stat, &fst);
|
if(!img) return NULL;
|
||||||
|
if(!img->data) return img; // empty "image" - no data inside
|
||||||
|
DBG("try to read, dt=%d, sz=%ld", img->dtype, naxes[0]*naxes[1]);
|
||||||
|
//int bscale = 1, bzero = 32768, status = 0;
|
||||||
|
//fits_set_bscale(fits->fp, bscale, bzero, &status);
|
||||||
|
//fits_read_img(fits->fp, img->dtype, 1, naxes[0]*naxes[1], NULL, img->data, &stat, &fst);
|
||||||
|
fits_read_img(fits->fp, TUSHORT, 1, naxes[0]*naxes[1], NULL, img->data, &stat, &fst);
|
||||||
if(fst){
|
if(fst){
|
||||||
fits_report_error(stderr, fst);
|
fits_report_error(stderr, fst);
|
||||||
image_free(&img);
|
image_free(&img);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user