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