github.com/astrogo/cfitsio@v0.1.0/phdu.go (about) 1 package cfitsio 2 3 // #include "go-cfitsio.h" 4 // #include "go-cfitsio-utils.h" 5 import "C" 6 7 import ( 8 "fmt" 9 "reflect" 10 "unsafe" 11 ) 12 13 // PrimaryHDU is the primary HDU 14 type PrimaryHDU struct { 15 ImageHDU 16 } 17 18 // Name returns the value of the 'EXTNAME' Card (or "PRIMARY" if none) 19 func (hdu *PrimaryHDU) Name() string { 20 card := hdu.header.Get("EXTNAME") 21 if card == nil { 22 return "PRIMARY" 23 } 24 return card.Value.(string) 25 } 26 27 // Version returns the value of the 'EXTVER' Card (or 1 if none) 28 func (hdu *PrimaryHDU) Version() int { 29 card := hdu.header.Get("EXTVER") 30 if card == nil { 31 return 1 32 } 33 rv := reflect.ValueOf(card.Value) 34 return int(rv.Int()) 35 } 36 37 // newPrimaryHDU returns a new PrimaryHDU attached to file f. 38 func newPrimaryHDU(f *File, hdr Header) (HDU, error) { 39 var err error 40 hdu := &PrimaryHDU{ 41 ImageHDU{ 42 f: f, 43 header: hdr, 44 }, 45 } 46 return hdu, err 47 } 48 49 // NewPrimaryHDU creates a new PrimaryHDU with Header hdr in File f. 50 // It returns an error if f already has a Primary HDU. 51 func NewPrimaryHDU(f *File, hdr Header) (HDU, error) { 52 var err error 53 54 naxes := len(hdr.axes) 55 c_naxes := C.int(naxes) 56 slice := (*reflect.SliceHeader)((unsafe.Pointer(&hdr.axes))) 57 c_axes := (*C.long)(unsafe.Pointer(slice.Data)) 58 c_status := C.int(0) 59 60 C.fits_create_img(f.c, C.int(hdr.bitpix), c_naxes, c_axes, &c_status) 61 if c_status > 0 { 62 return nil, to_err(c_status) 63 } 64 65 for icard := range hdr.slice { 66 card := &hdr.slice[icard] 67 c_name := C.CString(card.Name) 68 defer C.free(unsafe.Pointer(c_name)) 69 c_type := C.int(0) 70 c_status := C.int(0) 71 c_comm := C.CString(card.Comment) 72 defer C.free(unsafe.Pointer(c_comm)) 73 var c_ptr unsafe.Pointer 74 75 switch v := card.Value.(type) { 76 case bool: 77 c_type = C.TLOGICAL 78 c_value := C.char(0) // 'F' 79 if v { 80 c_value = 1 // 'T' 81 } 82 c_ptr = unsafe.Pointer(&c_value) 83 84 case byte: 85 c_type = C.TBYTE 86 c_ptr = unsafe.Pointer(&v) 87 88 case uint16: 89 c_type = C.TUSHORT 90 c_ptr = unsafe.Pointer(&v) 91 92 case uint32: 93 c_type = C.TUINT 94 c_ptr = unsafe.Pointer(&v) 95 96 case uint64: 97 c_type = C.TULONG 98 c_ptr = unsafe.Pointer(&v) 99 100 case uint: 101 c_type = C.TULONG 102 c_value := C.ulong(v) 103 c_ptr = unsafe.Pointer(&c_value) 104 105 case int8: 106 c_type = C.TSBYTE 107 c_ptr = unsafe.Pointer(&v) 108 109 case int16: 110 c_type = C.TSHORT 111 c_ptr = unsafe.Pointer(&v) 112 113 case int32: 114 c_type = C.TINT 115 c_ptr = unsafe.Pointer(&v) 116 117 case int64: 118 c_type = C.TLONG 119 c_ptr = unsafe.Pointer(&v) 120 121 case int: 122 c_type = C.TLONG 123 c_value := C.long(v) 124 c_ptr = unsafe.Pointer(&c_value) 125 126 case float32: 127 c_type = C.TFLOAT 128 c_ptr = unsafe.Pointer(&v) 129 130 case float64: 131 c_type = C.TDOUBLE 132 c_ptr = unsafe.Pointer(&v) 133 134 case complex64: 135 c_type = C.TCOMPLEX 136 c_ptr = unsafe.Pointer(&v) // FIXME: assumes same memory layout than C 137 138 case complex128: 139 c_type = C.TDBLCOMPLEX 140 c_ptr = unsafe.Pointer(&v) // FIXME: assumes same memory layout than C 141 142 case string: 143 c_type = C.TSTRING 144 c_value := C.CString(v) 145 defer C.free(unsafe.Pointer(c_value)) 146 c_ptr = unsafe.Pointer(c_value) 147 148 default: 149 panic(fmt.Errorf("cfitsio: invalid card type (%T)", v)) 150 } 151 152 C.fits_update_key(f.c, c_type, c_name, c_ptr, c_comm, &c_status) 153 154 if c_status > 0 { 155 return nil, to_err(c_status) 156 } 157 } 158 159 if len(f.hdus) > 0 { 160 return nil, fmt.Errorf("cfitsio: File has already a Primary HDU") 161 } 162 163 hdu, err := f.readHDU(0) 164 if err != nil { 165 return nil, err 166 } 167 f.hdus = append(f.hdus, hdu) 168 169 return hdu, err 170 } 171 172 // EOF